2010-02-03 10 views
9

Tengo el siguiente conjunto de plantillas:plantillas de especialización

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

Por favor alguien puede explicar por qué funcT(x1); llamadas de función # 3 y funcT(&x1); llamadas de función # 2 # 4, pero no como se esperaba?
Ya he leído este artículo http://www.gotw.ca/publications/mill17.htm que dice que "la resolución de sobrecarga ignora las especializaciones y funciona solo en las plantillas de función base". Pero de acuerdo con esta lógica funcT(x1); debe llamar a la función n. ° 1, no n. ° 3. Estoy confundido.

+0

esto parece relevante: http://www.gotw.ca/publications/mill17.htm –

+0

puedo enviarle un libro realmente bueno para esto: Addison Wesley - Plantillas C++ - La Guía Completa – erick2red

Respuesta

11

Las funciones # 3 y # 4 son especializaciones de # 1, no de # 1 y # 2 respectivamente.

Esto significa que su compilador elegirá primero entre # 1 y # 2. Cuando ha seleccionado # 1 para ser el mejor ajuste para funcT (x1), luego selecciona la especialización, # 3. Para funcT (& x1), elige # 2 como el mejor ajuste y no encuentra especializaciones.

Al escribir # 4 como

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

se convierte en una especialización de # 2 y obtendrá el resultado esperado que # 4 se llama a func (& x1).

Otra opción sería simplemente escribir

void funcT(int *arg) 

ya que siempre serán elegidos funciones regulares en lugar de versiones basados ​​en plantillas si coinciden.

+0

Derecha. Usted podría agregar eso, para hacer # 4 una especialización de # 2 y obtener el comportamiento "esperado", debe escribirse como 'template <> void funcT <> (int * arg)' –

+0

@ Éric Malenfant: correcto, I ' No estoy seguro de si su comentario o mi edición fue primero, pero gracias de todos modos. – villintehaspam

+0

¿Por qué es 'template <> void funcT <> (int * arg)' y no 'template <> void funcT (int * arg)'? – sepp2k

Cuestiones relacionadas