2009-12-03 10 views
40

テンプレートメンバ関数

template<class X> struct A { 
    template<int I> void f() {} 
}; 

template<class T> void g() 
{ 
    A<T> a; 
    a.f<3>(); // Compilation fails here (Line 18) 
} 

int main(int argc, char *argv[]) 
{ 
    g<int>(); // Line 23 
} 

コンパイラ(GCC)は言う:

hhh.cpp: In function 'void g()':

hhh.cpp:18: error: expected primary-expression before ')' token

hhh.cpp: In function 'void g() [with T = int]':

hhh.cpp:23: instantiated from here

hhh.cpp:18: error: invalid use of member (did you forget the '&' ?)

これは、なぜ誰も説明できますか?それを働かせる方法はありますか?

+1

エラーは? – Yacoby

+0

コンパイラは何について不平を言っていますか? – Romain

+1

それは私のために働く。どのようにg()を呼びますか? – philsquared

答えて

73

次のコードを試してみてください:14.2/4 C++ 03標準によると

template<class T> void g() 
{ 
    A<T> a; 
    a.template f<3>(); // add `template` keyword here 
} 

を:

When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template . Otherwise the name is assumed to name a non-template.

今後のC++標準はまだn2857 14.3/4を起草するに従って、このキーワードを必要としているようです。コンパイラの中には、エラーなしで元のコードをコンパイルできる特別なモードがあります(これは、緩和モードと呼ばれています)。

+5

このリンクも理由を説明しています:http:// publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/keyword_template_qualifier.htm –

+9

よく目に付きます - 私はいつもそのことを忘れています。事実VC++はこれを助けてくれることなく過去にすることができます – philsquared

+6

まあ...誰がそれを賞賛したのですか?私は前にこの構文を見たことがない。ありがとう。 – Ari

0

ここで、タイプTは定義されていますか?

関数g()を呼び出すときには、Tを知らなければなりません。そうでなければ、Tが未定義であるというコンパイラエラーの準備ができていなければなりません。

+0

g()を呼び出すと、「テンプレート引数がありません」というエラーが発生する可能性が高くなります – hirschhornsalz

+0

はい正しいです – Ashish

0

使用しているコンパイラを教えてください。問題のコードは、

int main() { 
    g<int>(); 
} 

を追加して問題なくコンパイルしました。Microsoft Visual Studio 9のcl.exeを使用してコンパイルしました。

私は試みたG ++のさまざまなバージョンで失敗しました。Comeauオンラインコンパイラもありました。

関連する問題