2010-02-03 9 views
9

Je l'ensemble des modèles suivants:spécialisation Modèles

//1 
template< typename T > void funcT(T arg) 
{ 
    std::cout<<"1: template< typename T > void funcT(T arg)"; 
} 
//2 
template< typename T > void funcT(T * arg) 
{ 
    std::cout<<"2: template< typename T > void funcT(T * arg)"; 
} 
//3 
template<> void funcT<int>(int arg) 
{ 
    std::cout<<"3: template<> void funcT<int>(int arg)"; 
} 
//4 
template<> void funcT< int * >(int * arg) 
{ 
    std::cout<<"4: template<> void funcT< int *>(int * arg)"; 
} 

//... 

int x1 = 10; 
funcT(x1); 
funcT(&x1); 

Quelqu'un peut-il s'il vous plaît expliquer pourquoi funcT(x1); fonction des appels # 3 et funcT(&x1); appels fonction # 2 mais pas # 4 comme prévu?
J'ai déjà lu cet article http://www.gotw.ca/publications/mill17.htm qui dit que "la résolution de surcharge ignore les spécialisations et fonctionne uniquement sur les modèles de fonction de base". Mais selon cette logique funcT(x1); devrait appeler la fonction # 1, pas # 3. Je suis confus.

+0

cela semble pertinent: http://www.gotw.ca/publications/mill17.htm –

+0

Je peux vous envoyer un livre vraiment bon pour cela: Addison Wesley - Modèles C++ - Le Guide complet – erick2red

Répondre

11

Les fonctions # 3 et # 4 sont des spécialisations de # 1, pas de # 1 et # 2 respectivement.

Cela signifie que votre compilateur choisira d'abord entre # 1 et # 2. Quand il a choisi # 1 pour être le meilleur ajustement pour funcT (x1), il sélectionne alors la spécialisation, # 3. Pour funcT (& x1), il choisit # 2 comme meilleur ajustement et ne trouve aucune spécialisation.

En écrivant # 4 comme

template<> void funcT<>(int * arg) 

il devient une spécialisation de 2 et vous obtiendrez le résultat attendu que # 4 est appelé à fonct (& x1).

Une autre option serait d'écrire simplement

void funcT(int *arg) 

puisque les fonctions régulières seront toujours choisis au lieu de versions si elles correspondent basé sur un modèle.

+0

Droit. Vous pourriez ajouter que, pour faire de # 4 une spécialisation de # 2 et obtenir le comportement "attendu", il devrait être écrit comme 'template <> void funcT <> (int * arg)' –

+0

@ Éric Malenfant: correct, je ' Je ne sais pas si votre commentaire ou ma modification est venu en premier, mais merci quand même. – villintehaspam

+0

Pourquoi est-ce 'template <> void funcT <> (int * arg)' et pas 'template <> void funcT (int * arg)'? – sepp2k