2010-07-22 6 views
76

Qu'est-ce qu'une portée dépendante et quelle est la signification de typename dans le contexte de l'erreur suivante?Modèles imbriqués avec portée dépendante

$ make 
g++ -std=gnu++0x main.cpp 
main.cpp:18:10: error: need 'typename' before 'ptrModel<std::vector<Data> >::Type' because 'ptrModel<std::vector<Data> >' is a dependent scope 
make: *** [all] Error 1 


/* 
* main.cpp 
*/ 

#include <vector> 
#include <memory> 

template<typename T> 
struct ptrModel 
{ 
typedef std::unique_ptr<T> Type; 
}; 


template<typename Data> 
struct ptrType 
{ 
typedef ptrModel< std::vector<Data> >::Type Type; 
}; 

int main() 
{ 
return 0; 
} 

Répondre

118

Le compilateur vous a dit exactement quoi faire. Ecrire typename avant ptrModel<std::vector<Data> >::Type, comme ceci:

typedef typename ptrModel<std::vector<Data> >::Type Type; 

La raison de cette exigence est que le compilateur ne sait pas à ce stade si ptrModel<std::vector<Data> >::Type décrit une variable de membre ou d'un type imbriqué. Il ne peut même pas comprendre cela en regardant la définition de ptrModel parce qu'il pourrait y avoir une spécialisation de ptrModel pour std::vector<Data> quelque part dans le programme qu'il n'a pas encore eu qui change lequel de ces choses ::Type se réfère à. Donc vous devez le dire explicitement.

Le nom ptrModel<std::vector<Data> >::Type a une "portée dépendante" car il est dans une portée que dépend sur l'instanciation d'un modèle.

+6

D'accord, mais n'est-il pas vrai que typedef une variable membre n'a pas de sens? – user383352

+5

Oui, mais cela n'est pas forcément utile en raison de certains détails sur la façon dont les modèles sont analysés par le compilateur. Voir la réponse acceptée à cette question: http://stackoverflow.com/questions/642229/why-do-i-need-to-use-typedef-typename-in-g-but-not-vs –

+5

J'ai aussi trouvé [ cette réponse] (http://stackoverflow.com/a/6571836/24874) pour être très utile lorsque vous rencontrez cette erreur et le concept pour la première fois. –

Questions connexes