2009-12-03 4 views
40

Cela ne compile pas:fonction membre modèle de classe modèle appelé de fonction de modèle

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 
} 

Le compilateur (gcc) dit:

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 '&' ?)

Quelqu'un peut-il expliquer pourquoi il en est? Y a-t-il un moyen de le faire fonctionner?

+1

Et l'erreur est? – Yacoby

+0

De quoi se plaint le compilateur? – Romain

+1

Ça marche pour moi. Comment invoquez-vous g()? (et quelle erreur obtenez-vous, comme d'autres l'ont demandé?) – philsquared

Répondre

73

Essayez le code suivant:

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

Selon C++ 03 standard 14.2/4:

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.

Future C++ standard semble être encore besoin ce mot-clé selon le projet n2857 14,3/4 . Certains compilateurs ont un mode spécial qui permet de compiler le code original sans erreurs (Comeau le compile dans ce qu'on appelle mode relaxé).

+5

Ce lien explique aussi pourquoi: http: // publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/keyword_template_qualifier.htm –

+9

bien repéré - j'oublie toujours celui-là. Le fait que VC++ le laisse passer sans rien ne sert à rien – philsquared

+6

Eh bien ... Qui le ferait! Je n'ai jamais vu cette syntaxe auparavant. Merci. – Ari

0

Où est défini le type T? Lorsque vous appelez la fonction g() à ce moment-là, le type T doit être connu sinon préparez-vous à une erreur de compilation en disant que T est indéfini.

+0

Si vous appelez g(), vous obtiendrez probablement une erreur "Argument de modèle manquant" – hirschhornsalz

+0

oui vous avez raison – Ashish

0

Pourriez-vous spécifier quel compilateur vous utilisez? Le code dans la question, avec

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

ajouté compilé sans problème à l'aide de cl.exe à partir de Microsoft Visual Studio 9;

Il a échoué sur différentes versions de G ++ que j'ai essayées, et le compilateur en ligne Comeau aussi.

Questions connexes