2010-06-16 3 views

Répondre

16

Lorsqu'un nom dépendant est utilisé pour faire référence à un modèle imbriqué, le nom imbriqué doit être préfixé avec le mot-clé template pour aider le compilateur à comprendre que vous faites référence à un modèle imbriqué et analyser le code correctement

template <typename T> 
void F(A<T> &a) 
{ 
    a.template f<0>(); 
} 

intérieur main le nom a ne dépend pas, ce qui est la raison pour laquelle vous ne avez pas besoin du mot-clé template supplémentaire. À l'intérieur F le nom a dépend, c'est pourquoi le mot-clé est nécessaire.

Ceci est similaire au mot clé supplémentaire typename lorsque vous faites référence à des noms de type imbriqués via un nom dépendant. Juste la syntaxe est légèrement différente.

1

Dans le premier, le compilateur pense que vous voulez dire ...

a.f < 0 ...gibberish.... 

réponse de Andrey corrige cela.

0

Notez qu'il ya sont extrait de code qui sont valides pour les deux le mot-clé ajouté et pas ajouté, ce qui donne des résultats différents dans chaque cas, même pour les modèles qui prennent des paramètres de type au lieu d'entiers.

#include <iostream> 

struct A { 
    template<typename T> 
    static A f(T) { 
    return A(); 
    } 

    template<typename T> operator T() { return T(); } 
}; 

template<typename U> 
int g() { 
    U u; 
    typedef A (*funcPtrType)(int()); 
    return !(funcPtrType)u.f < int() > (0); 
} 

int main() { 
    std::cout << g<A>() << std::endl; 
} 

Ce sorties 0 lorsqu'il est exécuté sans le mot-clé template ajouté. Si vous ajoutez le mot-clé avant f < int() >, il sort 1.


Explication

La version sans le mot-clé parse comme

funcPtrType temp1 = (funcPtrType)u.f; // taking func address 
bool temp2 = !temp1;     // temp2 == false 
bool temp3 = temp2 < int();   // temp3 == false 
bool temp4 = temp3 > (0);    // temp4 == false 
return temp4; 

Et la version avec le mot-clé parse comme

A temp1 = u.template f < int() > (0);  // function call 
funcPtrType temp2 = (funcPtrType) temp1; // temp2 == 0 
bool temp3 = !temp2;      // temp3 == true 
return temp3; 

Notez que temp2 est un pointeur NULL (produit par return T()). Des analyses différentes entières, et les deux sont valides! Cela a vraiment besoin d'un moyen de désambiguïsation - qui est d'insérer le mot-clé template le cas échéant.

Questions connexes