El problema y cómo superarlo en C ++
El problema ha sido explicado ampliamente por Pat y Matt . El compilador básicamente ignora la primera dimensión del tamaño de la matriz, ignorando efectivamente el tamaño del argumento pasado.
En C ++, por otro lado, puede superar fácilmente esta limitación de dos maneras:
- utilizando referencias
- utilizando
std::array
(desde C ++ 11)
Referencias
Si su función solo intenta leer o modificar una matriz existente (sin copiarla), puede usar referencias fácilmente.
Por ejemplo, supongamos que desea tener una función que restablezca una matriz de diez int
s configurando cada elemento 0
. Puede hacerlo fácilmente utilizando la siguiente firma de función:
void reset(int (&array)[10]) { ... }
No solo esto funcionará bien , sino que también impondrá la dimensión de la matriz .
También puede utilizar plantillas para hacer que el código anterior sea genérico :
template<class Type, std::size_t N>
void reset(Type (&array)[N]) { ... }
Y finalmente puedes aprovechar la const
corrección. Consideremos una función que imprime una matriz de 10 elementos:
void show(const int (&array)[10]) { ... }
Al aplicar el const
calificador estamos evitando posibles modificaciones .
La clase de biblioteca estándar para matrices.
Si considera que la sintaxis anterior es fea e innecesaria, como lo hago yo, podemos lanzarla a la lata y usarla std::array
en su lugar (desde C ++ 11).
Aquí está el código refactorizado:
void reset(std::array<int, 10>& array) { ... }
void show(std::array<int, 10> const& array) { ... }
¿No es maravilloso? Sin mencionar que el truco de código genérico que te enseñé anteriormente, todavía funciona:
template<class Type, std::size_t N>
void reset(std::array<Type, N>& array) { ... }
template<class Type, std::size_t N>
void show(const std::array<Type, N>& array) { ... }
No solo eso, sino que obtienes copias y movimientos semánticos gratis. :)
void copy(std::array<Type, N> array) {
// a copy of the original passed array
// is made and can be dealt with indipendently
// from the original
}
¿Entonces, Qué esperas? Ve a usar std::array
.
typedef
tipo de matriz. Por lo que la "decadencia de puntero" en los tipos de argumentos no es sólo azúcar sintáctico reemplazar[]
con*
, que realmente va a través del sistema de tipos. Esto tiene consecuencias en el mundo real para algunos tipos estándar como losva_list
que se pueden definir con tipo de matriz o sin matriz.int dis(char (*a)[1])
. A continuación, se pasa un puntero a una matriz:dis(&b)
. Si está dispuesto a usar características de C que no existen en C ++, también puede decir cosas comovoid foo(int data[static 256])
yint bar(double matrix[*][*])
, pero esa es una lata completamente diferente de gusanos.