2012-04-24 7 views
5

En el siguiente código, la función principal utiliza la función normal en lugar de la función de plantilla.Prioridad entre la función normal y la función de plantilla

#include <iostream> 

using namespace std; 

template <class T> 
void num(T t){cout<<"T : "<<t;} 

void num(int a){cout<<"wT : "<<a;} 


int main() 
{ 
    num(5); 
    return 0; 
} 

¿Cuál es la posible razón detrás de esto?

+2

funcionan mejor concordancia el argumento se elige primero. – Anycorn

+0

@Anycorn: en C++, ¿está predeterminado elegir la primera función normal? – IndieProgrammer

+0

Permítanme aclarar: si una función normal coincide con el * tipo *, se elegirá. por ejemplo, si fuera 'num (char a)', se elegiría temlate. – Anycorn

Respuesta

4

Para llamar al método de plantilla en este caso, debe invocar el método explícitamente con num<int>(5) en lugar de num(5). Aunque el compilador puede inferir, se prefiere el método no genérico a uno genérico. Puede echar un vistazo a este comportamiento aquí http://ideone.com/ccDJP.

+0

gracias. Quiero escuchar esta declaración: "Aunque el compilador puede inferir, preferirá un método no genérico a uno genérico". – IndieProgrammer

+0

Sí, si lo piensas bien, usar un método no genérico hace que se cree un nuevo método de plantilla en el texto (la plantilla de C++ esencialmente duplica el método para cada tipo diferente que se usa). ¿Por qué realizar ese esfuerzo si ya hay uno? –

+0

Manera alternativa de invocar la variante de plantilla 'num <> (5);'. – legends2k

7

Tome un vistazo a excelente artículo de Herb Sutter "Why not specialize function templates?"

Para citar:

"Por último, vamos a centrarnos en las plantillas de función única y considerar las reglas de sobrecarga para ver cuáles conseguir llama en diferentes situaciones de las reglas. son bastante simple, al menos en un nivel alto, y puede expresarse como un sistema de dos clases clásica:

  1. funciones Nontemplate son ciudadanos de primera clase. Se seleccionará una antigua función no estándar simple que coincida con los tipos de parámetros, así como con cualquier plantilla de función, en lugar de una plantilla de función que, de otro modo, sea igual de buena.

  2. Si no hay ciudadanos de primera clase para elegir que sean al menos tan buenos, entonces plantillas de función de fondo como los ciudadanos de segunda clase consulten a continuación. La plantilla base de función que se selecciona depende de cuál es la mejor y es la más especializada (nota importante: este uso de "especializado" no tiene nada que ver con especializaciones de plantilla, es un coloquialismo desafortunado) según un conjunto de reglas arcanas:

    • Si está claro que hay una plantilla base de función "más especializada", esa se acostumbra. Si esa plantilla base resulta ser especializada para los tipos que se utilizan, se utilizará la especialización, de lo contrario se utilizará la plantilla base instanciada con los tipos correctos.

    • Si existe un empate para la plantilla base de la función "más especializada", la llamada es ambigua porque el compilador no puede decidir cuál es una mejor coincidencia. El programador tendrá que hacer algo para calificar la llamada y decir cuál se quiere.

    • Porque si no hay ninguna plantilla base función que se puede hacer para que coincida, la llamada es mala y el programador tendrá que corregir el código."

En el ejemplo de código, como se señalado por David Z., la función no plantilla void num(int a) se seleccionará porque se corresponde con la primera regla. Cualquier plantilla de función adicional solo se considerará si concuerdan mejor.

Cuestiones relacionadas