2011-09-20 18 views
8

Estoy confundido por cómo la plantilla de creación de instancias de C++. Tengo un trozo de código:Creación de instancias de plantillas en C++

template <class T, int arraySize> 
void test1(T (&array)[arraySize]) 
{ 
    cout << typeid(T).name() << endl; 
} 

template<class T> 
void test2(T &array) 
{ 
    cout << typeid(T).name() << endl; 
} 

int main() 
{ 
    int abc[5]; 
    test1(abc); 
    test2(abc); 
    return 0; 
} 

Aquí están mis preguntas:
1. ¿De qué manera el tamaño de la matriz de ABC se pasa a test1 (el parámetro arraysize)?
2. ¿Cómo determina el compilador C++ el tipo de T en las dos plantillas?

+1

¿Quieres decir algo como 'test1 (abc)'? El segundo no tiene ningún sentido. Usted tiene una función 'test2 ' y la está indexando como si fuera una matriz ?! – Shahbaz

Respuesta

4

En test1 el compilador crea una plantilla con T [arraySize] siendo su forma. Cuando llama a test1 (abc) está proporcionando un argumento de entrada de tipo int [5] con el que coincida automáticamente el matcher de plantilla.

Sin embargo, si tuviera que escribir

int n=10; 
int *abc = new int[n]; 
test1(abc); 
test1<int,n>(abc); 

entonces la compilación fallaría y el compilador afirmaría que no tiene ninguna plantilla que coincida con el test1 (abc) llamada a la función o la int test1 <, n> (abc) llamada de función.

Esto se debe a que el tamaño de abc ahora se asigna dinámicamente y, por lo tanto, el tipo de abc es un puntero que tiene un tipo diferente y por lo tanto ninguna plantilla podría coincidir con las dos llamadas anteriores.

El código siguiente muestra algunos tipos

#include <iostream> 
using namespace std; 

template <class T> void printName() {cout<<typeid(T).name()<<endl;} 

int main() 
{  
    printName<int[2]>(); //type = A2_i 
    printName<int*>();  //type = Pi 

    getchar(); 
    return 0; 
} 
+1

además, ese 'abc [n]' no se compilará de todos modos, porque C++ no admite matrices de tamaño dinámico (ni siquiera C++ 11, hasta donde yo sé). Supongo que tienes un fondo C99? –

+0

Compiló bien bajo manzanas compilador llvm 3.0 sin embargo. Han actualizado la respuesta. Gracias por señalar eso. – twerdster

7
  1. no hay ningún parámetro que pasa en el sentido normal, ya que los parámetros de plantilla se resuelven en tiempo de compilación.
  2. Tanto arraySize como T se deducen del tipo del parámetro array. Desde que pasa un int[5], arraySize y T pasan a ser 5 y int, respectivamente, en tiempo de compilación.

Si, por ejemplo, usted declaró int* abc = new int[5];, el compilador vomitar en el punto que intenta llamar test1(abc). Además de una discrepancia de tipo básica, int* no contiene suficiente información para inferir el tamaño de la matriz.

5

Se llama plantilla deducción de argumento.

El tipo deabc a la vista en el sitio es: int(&)[5] que tiene dos información combinada: int y 5. Y la plantilla de función acepta argumento de tipo T(&)[N], pero el argumento en call-site es int(&)[5], por lo que el compilador deduce que T es int y N es 5.

Lea estas:

Cuestiones relacionadas