2008-12-23 48 views
8

Si se crea un archivo:No se puede convertir (*) [] para **

test.cpp:

void f(double **a) { 

} 

int main() { 
    double var[4][2]; 
    f(var); 
} 

Y a continuación, ejecute: g ++ test.cpp -o prueba

Obtengo

test.cpp: In function `int main()': 
test.cpp:8: error: cannot convert `double (*)[2]' to `double**' for argument `1' 
to `void f(double**)' 

¿Por qué no puedo hacer esto?

¿No es doble var [4] [2] es lo mismo que hacer double ** var y luego asignar la memoria?

Respuesta

17

C++ strings: [] vs. *

Mira el Excursión: Las matrices multidimensionales que describe cómo pasar matrices multidimensionales a funciones como argumentos. Basicially que desee cambiar su código en esto:

// same as void f(double (*a)[2]) { 
void f(double a[][2]) { 

} 

int main() { 
    // note. this is not a pointer to a pointer, 
    // but an array of arrays (4 arrays of type double[2]) 
    double var[4][2]; 

    // trying to pass it by value will pass a pointer to its 
    // first element 
    f(var); 
} 

Todos menos los últimos dimensiones tienen que ser conocido por la función llamada. De lo contrario, la indexación de la matriz, el compilador no sería capaz de calcular la distancia correcta a los valores en su matriz (a [1] es sizeof(double[2]) bytes de distancia de un [0]).

Parece que desea poder aceptar la matriz sin saber el tamaño de las dimensiones. Puede utilizar plantillas para esto:

template<std::size_t N> 
void f(double a[][N]) { 
    // N == 2 for us 
} 

int main() { 
    double var[4][2]; 
    f(var); 
} 

El compilador hará una copia de (instantiate) esa plantilla para cada valor de N se utiliza con la función, auto-deducir la derecha N.

+0

Gracias, me gusta el enlace que me diste ya que puedo obtener una visión más profunda desde allí. Y también el ejemplo de plantilla que me diste. double a [] [2] es exactamente lo que necesito en mi programa en particular. – Ezequiel

0

El problema es que un doble ** es un puntero a un puntero. Su función 'f' quiere pasar la dirección de un puntero a un doble. Si llamas a f (var), bien, ¿dónde crees exactamente que es ese puntero? No existe.

Esto funcionará:

double *tmp = (double *) var; 
f (&tmp); 

Además, sería trabajar para cambiar la definición de f:

void f (double a[4][2]) { } 

Ahora f toma un puntero al tipo de matriz que tiene. Que funcionará.

+1

no, eso no funciona. su función f toma el doble **, y no un puntero a una matriz. y también tu conversión a doble * es incorrecta. simplemente no es correcto lanzar un doble [4] [2] a un doble * y esperar que funcione. por las razones que indiqué arriba. por favor no hagas esto –

+0

Tiene razón, mi declaración no coincide con lo que estaba tratando de hacer. –

+1

Por "trabajo" quieres decir "fracasar horriblemente", ¿verdad? Nunca arrojes valores a ciegas. –

Cuestiones relacionadas