2011-06-21 17 views
5

Duplicar posibles:
why isnt it legal to convert (pointer to pointer to non-const) to a (pointer to pointer to a const)qué int no puede ** puede convertir en const int ** en C++

Hola tengo el siguiente código, pero no puedo envolver mi cabeza en torno a por qué esto no funciona - Recibo un error que dice "no puedo convertir de int ** a const int **". Sin embargo, si cambio el primer argumento de printValues ​​para que sea "const int * const * myArray", todo funciona bien. Sé que probablemente no debería usar el de abajo de todos modos, pero no entiendo por qué no compila en absoluto. ¿No puede tener un puntero a un puntero a un entero constante sin declararlo constante en main()?

#include <iostream> 

int printValues(const int ** myArray, const long nRows, const long nCols) 
{ 
for (long iRow = 0; iRow < nRows; iRow++) 
{ 
    for (long iCol = 0; iCol < nCols; iCol++) 
    { 
     std::cout << myArray[iRow][iCol] << " "; 
    } 
    std::cout << "\n"; 
} 
return 0; 

} 

int main() 
{ 
const long nRows = 5; 
const long nCols = 8; 

int** myArray = new int* [nRows]; 

for (long iRow = 0; iRow < nRows; iRow++) 
{ 
    myArray[iRow] = new int [nCols]; 
} 

for (long iRow = 0; iRow < nRows; iRow++) 
{ 
    for (long iCol = 0; iCol < nCols; iCol++) 
    { 
     myArray[iRow][iCol] = 1; 
    } 
} 

printValues(myArray, nRows, nCols); 

return 0; 
} 
+5

Ver ["¿Por qué me sale un error al convertir un Foo ** → Foo const **?"] (Http://www.parashift.com/c++faq-lite/const-correctness.html#faq- 18.17) –

+0

Porque realmente le permite violar la corrección de const. Trataré de encontrar el dup. –

+0

Nunca me di cuenta de que esta era una pregunta tan popular, de todas las respuestas que he visto siento que [la de estándar] (http://stackoverflow.com/a/29240053/1708801) es la mejor. –

Respuesta

1

Editar:

Usted está violando const-corrección. Al decir que desea un apuntador a un puntero, se está configurando permitiendo que se modifique el objeto const original. Const es un contrato. Al permitir que esto suceda sin un yeso, te estás configurando para permitir que un objeto const sea modificado más adelante.

+1

Siempre puede convertir non-'const' a 'const'. Lea el enlace de @James McNellis sobre por qué este escenario específico convierte 'const' a no-'const'. –

+0

(en referencia al comentario de 0A0D) Eso también es cierto si cambio el argumento de la función a "const int * const * myArray", ¿o no? Y compila felizmente si hago eso –

+0

@ 0A0D: No sé a qué te refieres con eso.Puedes hacer 'void something (int * foo) {const int bar = * foo; } 'todo el día. –

6
  • int ** es: "un puntero a un puntero a un número entero".
  • const int ** es: "un puntero a un puntero a un entero constante".

Una analogía descabellada:

  • una nota que describe la ubicación de otra nota que describe la ubicación de un tarro
  • una nota que describe la ubicación de otra nota que describe la ubicación de un cerrada frasco

Sólo se puede colocar una cookie dentro de un frasco que no está cerrada.

Ahora, piense en reemplazar la segunda nota con una fotocopia de la primera nota. ¿Tiene alguna garantía de que el último contenedor al que apunta esta nota se cerrará y no podrá aceptar cookies? El uso de const es un contrato y no puede cumplir este contrato al navegar por la indirección de dos referencias.

+0

Es mejor explicar esto por código, que por jar y cookie. jar y cookie no son semánticas de C++, por lo que sería muy difícil ver el error si hay alguno en la analogía. – Nawaz

+0

@Nawaz: A la mayoría de las personas les resulta difícil concentrarse en los consejos, por lo que pensé que sería útil un ejemplo tangible. Dejé que otros lo expresaran en términos de código ... –

+3

Las cookies son ciertamente más deliciosas que los indicadores. –

1

Básicamente, esto se debe a que es posible cambiando el nivel de direccionamiento indirecto y otras semánticas válidas y no violentas que puede trabajar en el entorno si solo está en el nivel superior. Tienes que agregar const en más de un nivel para que el const sea realmente seguro.

Cuestiones relacionadas