2012-05-08 11 views
8

Esta pregunta se trata de funciones que toman matrices de tamaño estáticamente conocido.La diferencia entre int a [5] e int (& a) [5] en la deducción del parámetro de plantilla

Tomemos como ejemplo el siguiente programa mínimo:

#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; 
} 

Lo cual, cuando se ejecuta, imprime el resultado esperado:

2 3 4 5 6 
3 4 5 6 7 

Sin embargo, cuando traté de tener mi compilador (VS 2010) deducir el 5, es could not deduce template argument for 'int [n]' from 'int [5]'.

Un poco de investigación dio como resultado la arrfun_b actualizada cuando la deducción parámetro de plantilla funciona:

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

El resultado del programa es el mismo, ya sea arrfun_a o arrfun_b se llama.

Hasta ahora, la única diferencia que he encontrado es si la deducción argumento de plantilla funciona y si es posible llamar la función con una N que no es de 5 ...

+2

¿Estás seguro de que "ambas versiones permiten pasar explícitamente una N que es más pequeña o más grande"? No debería y [no] (http://ideone.com/74FaV) para mí. Y es otro _pro_ usar la versión de referencia – Lol4t0

+0

¡Gracias por arreglar mi confusión! En algún lugar durante la prueba, ¡debo haberlo arruinado! –

+0

No debe eliminar la versión que no es de referencia y creó una sobrecarga, que se llamó. – Lol4t0

Respuesta

14

El compilador cambia el tipo de silencio función argumento int a[N] a int *a y por lo tanto pierde el tamaño de la matriz. int(&a)[5] es realmente una referencia a una matriz de tamaño 5, y no se puede pasar una matriz de cualquier otro tamaño.

+5

Más importante, 'int a [5]' se convierte en 'int * a' en una lista de parámetros donde' int (& a) [5] 'es realmente ** referencia ** a una matriz de 5' int's –

+1

@D. Shawley, lo insinué pero no lo expliqué. Gracias. –

+0

En ese caso, la llamada a 'arrfun_a' incluiría un decaimiento de matriz a puntero seguido de una conversión implícita de puntero a matriz de cinco, dejándome con un mensaje de compilador totalmente inútil * genial * –

1

Creo que es la diferencia entre una referencia y un puntero.

arrfun_a pasa un puntero a int.

arrfun_b pasa una referencia a una matriz de ints.

Cuestiones relacionadas