2010-08-07 12 views
7

¿El C++ garantía estándar de la siguiente ?:estándar de C++, sobrecargado resolución de funciones/juego

template<typename T> 
void function(T (&)[1]); 

template<typename T> 
void function(T*); 

int a[1]; 
function(a); // first function gets called, not second version 
+0

Me gustaría saber también. – zneak

+2

Buena pregunta, pero el tema de la pregunta no tanto. ¿Cree que podría hacerlo más relevante, como "Es el tipo de parámetro T (&) [1] una mejor coincidencia que T * para una matriz en plantillas de C++", por ejemplo. Por cierto, no estoy seguro de si tiene algo que ver con la sobrecarga. –

+0

@Mac He cambiado un poco los temas, ¿es mejor? – Anycorn

Respuesta

6

Sí, esto está garantizado, pero la razón es diferente a lo que dice GMan. La sobrecarga de "matriz de longitud 1" se seleccionará porque es más especializada que la segunda en el orden parcial de funciones de plantilla. Básicamente, significa que un argumento en el formulario T(&)[1] siempre coincidirá con el segundo argumento de plantilla en el formulario T*, por lo que la primera sobrecarga siempre se seleccionará cuando las secuencias de conversión no decidan.

De 13.3.3:

Teniendo en cuenta estas definiciones, un viable función F1 se define para ser un mejor función que la otra función viable F2 si para todos los argumentos i, ICSI (F1) es no una secuencia de conversión peor que ICSI (F2), y luego

  • por alguna argumento j, ICSj (F1) es una sucesión de conversión mejor que ICSj (F2), o, si no que,

  • F1 es una función no-plantilla y F2 es una especialización función de plantilla, o, si no que,

  • F1 y F2 son funciones de plantilla, y la plantilla de función para F1 es más especializado que la placa tem- para F2 de acuerdo con las reglas de ordenación parciales descritas en 14.5.5.2, o, si no que,

...

Las funciones normales solo se ven afectadas por el primer elemento; cuando cualquier función de plantilla está en el conjunto de funciones candidatas, el segundo o tercer elemento puede decidir. La razón por la que queremos que sea así es que queremos poder escribir sobrecargas de plantillas aparentemente ambiguas. P.ej.

template <class T> void f(T); 
template <class T> void f(T*); 

de otro modo sería ambigua para int*. En C++ 0x, incluso se puede escribir declaraciones como:

template <class ...Ts>   void f(const Ts&... args); 
template <class T, class ... Ts> void f(const T& a, const Ts&... args); 

y el segundo será seleccionado cada vez que hay al menos un argumento.

+0

De @aaa en mi respuesta eliminada: @jpa Entonces, la presencia de plantilla es lo que hace una gran diferencia? – GManNickG

+0

@GMan: Sí, mira editar. – jpalecek