2011-09-20 10 views
8

Sono confuso dal modello di istanza di C++. Ho un pezzo di codice:Istanza di modelli in 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; 
} 

Ecco le mie domande:
1. In che modo la dimensione della matrice abc viene passato al TEST1 (il parametro arraysize)?
2. In che modo il compilatore C++ determina il tipo di T nei due modelli?

+1

Vuoi dire qualcosa del tipo 'test1 (abc)'? Il secondo non ha alcun senso. Hai una funzione 'test2 ' e la stai indicizzando come se fosse un array ?! – Shahbaz

risposta

4

In test1 il compilatore crea un modello con T [arraySize] che è la sua forma. Quando si chiama test1 (abc) si fornisce un argomento di input di tipo int [5] a cui corrisponde automaticamente il matcher del template.

Tuttavia, se si dovesse scrivere

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

quindi la compilazione fallirebbe e il compilatore sarebbe affermare che non ha alcun modello corrispondente al test1 (abc) chiamata di funzione o l'int test1 <, n> (abc) chiamata di funzione.

Questo perché la dimensione di abc è ora allocata dinamicamente e quindi il tipo di abc è un puntatore che ha un diverso tipo e quindi nessun modello può essere abbinato alle due chiamate precedenti.

Il codice seguente mostra alcuni tipi

#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

inoltre, che 'abc [n]' non verrà compilato comunque, perché C++ non supporta matrici di dimensioni dinamiche (nemmeno C++ 11, per quanto ne so). Immagino tu abbia uno sfondo C99? –

+0

Compilò bene sotto apple llvm compilatore 3.0. Ho aggiornato la risposta. Grazie per la segnalazione. – twerdster

7
  1. non esiste un parametro che passa nel senso normale, dal momento che i parametri del modello vengono risolte al momento della compilazione.
  2. Entrambi arraySize e T vengono dedotti dal tipo del parametro array. Poiché si passa un int[5], e T diventa 5 e int, rispettivamente, in fase di compilazione.

Se, ad esempio, è dichiarato int* abc = new int[5];, il compilatore sarebbe barf nel punto che si tenta di chiamare test1(abc). A parte una mancata corrispondenza di tipo di base, int* non contiene informazioni sufficienti per dedurre la dimensione dell'array.

5

Si chiama deduzione argomento modello.

Il tipo di abc al call-sito è: int(&)[5] che ha due informazioni combinato: int e 5. E il modello di funzione accetta l'argomento di tipo T(&)[N], ma l'argomento sul sito di chiamata è, int(&)[5], quindi il compilatore deduce che T è int e N è 5.

leggiamo queste: