2010-02-03 11 views
9

Ho la seguente serie di modelli:modelli di specializzazione

//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); 

Qualcuno può spiegare perché funcT(x1); chiamate di funzione # 3 e funcT(&x1); chiamate di funzione # 2, ma non 4 # come previsto?
Ho già letto questo articolo http://www.gotw.ca/publications/mill17.htm che dice che "la risoluzione di sovraccarico ignora le specializzazioni e opera solo sui modelli di funzione di base". Ma secondo questa logica funcT(x1); dovrebbe chiamare la funzione # 1, non # 3. Sono confuso.

+0

questo sembra pertinente: http://www.gotw.ca/publications/mill17.htm –

+0

posso inviare un libro davvero buono per questo: Addison Wesley - Modelli C++ - La guida completa – erick2red

risposta

11

Le funzioni # 3 e # 4 sono le specializzazioni del numero 1, non del numero 1 e del numero 2 rispettivamente.

Ciò significa che il compilatore sceglierà prima tra 1 e 2. Quando ha selezionato # 1 come migliore per funcT (x1), seleziona la specializzazione, # 3. Per funcT (& x1), sceglie il 2 come miglior adattamento e non trova specializzazioni.

Scrivendo # 4 come

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

diventa una specializzazione di 2 # e si otterrà il risultato previsto che il 4 # è chiamato per FUNCT (& x1).

Un'altra opzione sarebbe quella di scrivere semplicemente

void funcT(int *arg) 

poiché le funzioni regolari saranno sempre essere scelto al posto di versioni basati su modelli se corrispondono.

+0

Giusto. Potresti aggiungere che, per rendere # 4 una specializzazione della # 2 e ottenere il comportamento "previsto", dovrebbe essere scritto come 'template <> void funcT <> (int * arg)' –

+0

@ Éric Malenfant: corretto, I ' Non sono sicuro che il tuo commento o la mia modifica siano arrivati ​​prima, ma grazie comunque. – villintehaspam

+0

Perché 'template <> void funcT <> (int * arg)' e non 'template <> void funcT (int * arg)'? – sepp2k

Problemi correlati