2012-05-08 16 views
8

Questa domanda riguarda le funzioni che utilizzano matrici di dimensioni statiche note.La differenza tra int a [5] e int (& a) [5] nella deduzione dei parametri del modello

Prendiamo ad esempio il seguente programma minimo:

#include <iostream> 

template<size_t N> 
void arrfun_a(int a[N]) 
{ 
    for(size_t i = 0; i < N; ++i) 
     std::cout << a[i]++ << " "; 
} 

int main() 
{ 
    int a[] = { 1, 2, 3, 4, 5 }; 
    arrfun_a<5>(a); 
    std::cout << std::endl; 
    arrfun_a<5>(a); 

    return 0; 
} 

che, una volta eseguito, stampa il risultato atteso:

2 3 4 5 6 
3 4 5 6 7 

Tuttavia, quando ho cercato di avere il mio compilatore (VS 2010) deduce il 5, è could not deduce template argument for 'int [n]' from 'int [5]'.

Un po 'di ricerca portato alla aggiornato arrfun_b dove il parametro di template detrazione funziona:

template<size_t n> 
void arrfun_b(int (&a)[n]) 
{ 
    for(size_t i = 0; i < n; ++i) 
     std::cout << ++(a[i]) << std::endl; 
} 

Il risultato del programma è la stessa, sia arrfun_a o arrfun_b si chiama.

Finora, l'unica differenza che ho trovato è se la deduzione modello argomento funziona e se è possibile chiamare la funzione con una N che non è 5 ...

+2

Sei sicuro che "entrambe le versioni consentono di passare esplicitamente un N più piccolo o più grande"? Non dovrebbe e [non] (http://ideone.com/74FaV) per me. Ed è un altro _pro_ usare la versione di riferimento – Lol4t0

+0

Grazie per aver sistemato la mia confusione! A un certo punto durante i test, devo averlo incasinato! –

+0

Non è necessario eliminare la versione non di riferimento e creato un sovraccarico, che è stato chiamato. – Lol4t0

risposta

14

Il compilatore cambia silenziosamente il tipo di funzione argomento int a[N] a int *a e quindi perde la dimensione della matrice. int(&a)[5] è veramente un riferimento a un array di dimensione 5 e non può essere passato a un array di altre dimensioni.

+5

Altro importantemente, 'int a [5]' diventa 'int * a' in una lista di parametri dove' int (& a) [5] 'è veramente un ** riferimento ** a un array di 5' int's –

+1

@D. Shawley, l'ho sottinteso, ma non l'ho reso esplicito. Grazie. –

+0

In questo caso, la chiamata a 'arrfun_a' includerebbe un decadimento array-to-pointer seguito da una conversione implicita da pointer a array di cinque, lasciandomi un messaggio del compilatore totalmente inutile? * great * –

1

Penso che sia la differenza tra un riferimento e un puntatore.

arrfun_a passa un puntatore a int.

arrfun_b passa un riferimento a un array di ints.

Problemi correlati