2016-11-09 14 views
2

Iてきた次のテンプレートクラス&サンプルクラスに応じて設定する方法:、デフォルトのテンプレートパラメータとして、ネストされたテンプレートクラスのインスタンス化は、他のパラメータ

template<typename A, typename B, typename C = typename A::Nested<B>> 
struct X 
{ 
    X() 
    { 
     std::cout << "A is : " << A::who() << std::endl; 
     std::cout << "B is : " << B::who() << std::endl; 
     std::cout << "C is : " << C::who() << std::endl; 
    } 
}; 

struct Bsample 
{ 
    static const char* who() { return "Bsample"; } 
}; 

struct Asample 
{ 
    template<typename B> 
    struct Nested; 
    template<> 
    struct Nested<Bsample> 
    { 
     static const char* who() { return "Asample::Nested<Bsample>"; } 
    }; 
    static const char* who() { return "Asample"; } 
}; 

vc14を使用して、上記のコードはうまくコンパイルして生成インスタンス化のための予期される振る舞いは、デフォルトテンプレートパラメータCAsample::Nested<Bsample>X<Asample, Bsample>です。 GCC 5.1でコンパイルするとき

はしかし、私は次のエラーを取得する:

prog.cpp:4:65: error: expected '>' before '<' token 
template<typename A, typename B, typename C = typename A::Nested<B>> 
                   ^

私は、templatetypenameを使用して、テンプレートパラメータCのデフォルト値を宣言するために、いくつかの組み合わせを試してみました...しかし、しませんでしたこのコードをGCCでコンパイルすることに成功しました。

このコードをC++標準に準拠させ、GCCでコンパイルするにはどうすればいいですか?ヘルプ

EDITため

ありがとう:TartanLlamaから受け入れ答えに加えてTartanLlama

から受け入れ答えのほかには、私はまた、テンプレートパラメータのbraketsを終了する間に空白(スペース)を挿入する必要がありました:

template<typename A, typename B, typename C = typename A::Nested<B> > 
//          blank (space) added here^

そうでない場合は、GCCは(オプション-std=c++11が指定されていない)、次のエラーを発行します。

あなたがここに typename templateの両方が必要
error: spurious '>>', use '>' to terminate a template argument list 
template<typename A, typename B, typename C = typename A::template Nested<B>> 
                      ^
+0

これは単に 'template'と' typename'だけではないので、私は再度投票することにしました。そして、OPは彼らの使い方を認識しているようですが、ここにそれをどのように適用するかはわかりません。 – TartanLlama

+0

@ TartanLlama:悲しいことに、人々は光よりも早く質問を終わらせ、最後まで読んでいない人もいます(私はこれまで人を近づけたアイデアを持っています)。 – shrike

答えて

4

template<typename A, typename B, typename C = typename A::template Nested<B>> 

templateA::Nestedがテンプレートであるよりも、言う、とtypenameA::Nested<B>名前タイプと言います。

またAsample定義のうち、Asample::Nestedの専門を移動する必要があります。

template<typename A, typename B, typename C = typename A::template Nested<B>> 
struct X 
{ 
    // ... 

struct Asample 
{ 
    template<typename B> 
    struct Nested; 

    static const char* who() { return "Asample"; } 
}; 

template<> 
struct Asample::Nested<Bsample> 
{ 
    static const char* who() { return "Asample::Nested<Bsample>"; } 
}; 

Live demo

+0

私は実際にあなたの答えで提案しているように、デフォルトのテンプレートパラメータの宣言を試みましたが、gcc: 'spurious '>>から奇妙なエラーがあり、'> 'を使ってテンプレート引数リストを終了しました。私は、gccが最後の '>> 'を抽出演算子として解釈したことを理解しました。ブラケットを閉じる間にブランクを挿入することで問題が解決しました。 (あなたが望むなら答えを更新するかもしれません;そうでなければ私はあなたの質問を更新します)とにかく、私は問題に2つの主な修正を提供するので、あなたの答えを受け入れます。ありがとう。 – shrike

+0

@shrikeええ、あなたはそれらの間にスペースが必要でしたが、C++ 11で修正されました。 – TartanLlama

1

あなたはテンプレートであるNestedコンパイラに指示する必要がありますいずれにせよ、あなたのコードは異なるエラーのためにコンパイルされません:

error: explicit specialization in non-namespace scope 'struct Asample' 
    template<> 

名前空間のスコープでNestedを特化する必要があります。

関連する問題