2010-03-17 9 views

Respuesta

20

Ver Why am I getting an error converting a Foo** → const Foo**?

Debido a la conversión de Foo**const Foo** no sería válida y peligroso ... La razón por la conversión de Foo**const Foo** es peligroso es que le dejaría en silencio y sin querer modificar un objeto constante y sin Foo un molde

La referencia continúa para dar un ejemplo de cómo una conversión implícita de este tipo podría permitirme modificar un objeto const sin un molde.

+3

Quizás un resumen agregue más a su respuesta. – GManNickG

18

Esta es una restricción muy difícil. Está relacionado con las reglas de aliasing del lenguaje. Echar un vistazo a lo que dicen las normas, porque me he enfrentado a esto antes:

(Página 61)

[Nota: si un programa puede asignar un puntero de tipo T ** a un puntero de tipo const T ** (es decir, si se permitió la línea // 1 debajo), un programa podría modificar inadvertidamente un objeto const (como se hace en la línea // 2). Para ejemplo,

int main() { 
    const char c = 'c'; 
    char* pc; 
    const char** pcc = &pc; //1: not allowed 
    *pcc = &c; 
    *pc = 'C'; //2: modifies a const object 
} 

-fin nota]

8

Si ha convertido el parámetro a const float** que luego podría almacenar una const float* en la posición de memoria en los puntos de parámetros a. Pero la función de llamada cree que se supone que esta ubicación de memoria contiene un float* no const y podría intentar más tarde cambiar este apuntado a float.

Por lo tanto, no puede convertir float** en const float**, le permitiría almacenar punteros a constantes en ubicaciones donde se esperan punteros a valores mutables.

Para obtener más información, consulte el C++ FAQ Lite.

+0

+1 - la mejor respuesta. – JonH

10

Otros autores han explicado por qué esto es un error en C++.

Déjame responder la pregunta detrás de tu pregunta. Quería indicar, en la interfaz de su función, que su función no modificará los valores flotantes contenidos en la matriz. Buena intención, y permite que su función se llame con matrices const float **. La pregunta detrás de su pregunta sería, cómo lograr esto sin resolver feos moldes.

La forma correcta de lograr lo que desea es cambiar el tipo de su parámetro de función a const float * const *.

El adicional const entre las estrellas le asegura al compilador que su método no intentará almacenar punteros para const float en la matriz, ya que este tipo declara que los valores del puntero también son const.

Ahora puede llamar a esta función con float ** (que era el ejemplo en su pregunta), const float ** y const float * const * argumentos.

+0

Sí. La regla para la sintaxis const es que si está a la izquierda de un tipo, se une fuertemente a la cosa a la derecha de la misma, de lo contrario modifica la cosa a la izquierda de la misma. Así 'const int' y' int const' son del mismo tipo, 'const int *' y 'int const *' son ambos punteros a un 'int' que es const,' int * const' es un puntero que no se puede cambie a 'int' puede, y' const int * const' y 'int const * const' son punteros que no puede cambiar a' int's no puede cambiar. Extender indefinidamente. – Ben

+0

"La forma correcta de lograr lo que quería es cambiar el tipo de parámetro de su función a const float * const *." Exactamente lo que estaba buscando, esta respuesta debería estar más arriba. –

+0

¿Qué sucede si estoy llamando a una API con la firma 'foo (const char ** bar)'? No tengo control sobre la API, ¿cómo puedo resolver este error en la llamada a la función? –

Cuestiones relacionadas