2012-01-25 13 views
3

g ++を使用してMicrosoft Visual C++コードをコンパイルしようとしています。今私は本当に理解できないコンパイラエラーに遭遇しました。 (簡体字)のコードは次のようになります。私はグラムでこれをコンパイルしようとすると(バージョン4.4.5)++テンプレートベースクラスメンバでg ++コンパイラエラー

template<int X> struct A { 
    template<class Ret> static Ret call() { 
     return 0; 
    } 
}; 

template<int X> struct B : A<X> { 
    int f() { 
     return A<X>::call<int>(); 
    } 
}; 

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

main.cpp: In member function int B<X>::f(): 
main.cpp:16: error: expected primary-expression before int 
main.cpp:16: error: expected ; before int 
main.cpp:16: error: expected unqualified-id before > token 

私はテンプレートの種類を削除した場合(Ret)メソッドA :: callから、コードはうまくコンパイルされます。誰もここで何が間違って見える?

ありがとうございます!

+0

[どこで、なぜ私は「テンプレート」と「型名」のキーワードを入れなければならないのですか?](http://stackoverflow.com/questions/610245/where-and-why-do-の可能重複テンプレートとタイプ名のキーワードを持つ必要があります) –

答えて

5

あなたはtemplateキーワードが必要です。

return A<X>::template call<int>(); 

callは、その意義は、コンパイラプロセスf()知られていないテンプレートパラメータに依存することを意味し、依存名です。 callは、それに接頭辞「template」を付けて機能テンプレートであることを示す必要があります。

あなたは、ネストされたタイプにアクセスしようとすると、同じことが起こる:

template <typename T> 
struct A { typedef int type; }; 

template <typename T> 
void f() 
{ 
    typename A<T>::type i = 0; // notice "typename" here 
} 

そして、時にはあなたも、両方を混在させる必要があります:あなたは名前が型を示したことを示すためにtypenameキーワードを追加する必要があります

template <typename T> 
struct A 
{ 
    template <typename U> 
    struct inner { }; 
}; 

template <typename T> 
void f() 
{ 
    typename A<T>::template inner<int> var; 
} 

これら二つのキーワードの使用徹底的にこの質問への回答で説明されています。Where and why do I have to put the “template” and “typename” keywords?(リンクを見つけるための@ビョルンPollexに感謝)。

+0

[この質問](http://stackoverflow.com/questions/610245/)では、この必要性がいつ、なぜ必要なのかを詳しく説明しています。 –

+0

@BjörnPollex:ありがとう、私は実際にこの正確な質問:)を探していた! –

5

Aはテンプレートであり、Xを知らないと、コンパイラはA<X>の内容を判断できません。特にcallがテンプレートになることはわかりません。

あなたがtemplateキーワードを使用する必要がコンパイラにそれを伝えるために:あなたはそれをテンプレートクラスの一部だとして、あなたが呼び出している関数は、テンプレートであることを指定する必要があり

template<int X> struct B : A<X> { 
    int f() { 
     return A<X>::template call<int>(); 
    } 
}; 
3

。コンパイラは、A<X>に与えられたテンプレート関数がcallであることを認識していないので、それを助ける必要があります。

template<int X> struct B : A<X> { 
    int f() { 
     return A<X>::template call<int>(); 
    } 
};