c++ types

c++ - char* c



Conversión de C++: char** a const char** (1)

Esta pregunta ya tiene una respuesta aquí:

En C ++, ¿por qué no es posible pasar un char** como un argumento a una función que acepta const char** , cuando es posible una conversión de char* a const char* , como se muestra a continuación?

void f1(const char** a) { } void f2(const char* b) { } int main(int argc, char const *argv[]) { char* c; f1(&c); // doesn''t work f2(c); //works return 0; }

La salida del compilador es

test.cpp: In function ''int main(int, const char**)'': test.cpp:15:10: error: invalid conversion from ''char**'' to ''const char**'' [-fpermissive] test.cpp:1:6: error: initializing argument 1 of ''void f1(const char**)'' [-fpermissive]


Es necesario proteger los contenidos en ambos niveles de desreferencia del puntero. Con const char** usted podría realmente modificar los contenidos en la primera desreferencia.

char *tmp = "foo"; //Deprecated but it''s ok for the example void f1(const char** a) { a[0] = tmp; //this is legal a[0][1] = ''x''; //this is not }

Y esto es muy probable que no sea la intención. Debe tener un aspecto como este:

char *tmp = "foo"; //Deprecated but it''s ok for the example void f1(char const* const* a) { a[0] = tmp; // this is not legal any more a[0][1] = ''x''; // this still upsets compiler }

El compilador no permite la conversión implícita a tales tipos de punteros protegidos "parcialmente". Permitir dicha conversión podría tener consecuencias desagradables como se explica en parashift.com/c++-faq/constptrptr-conversion.html señalado en el comentario de @zmb. Esta answer también menciona cómo se podría violar la constancia de un objeto si se permitiera, utilizando ejemplos de caracteres.

Sin embargo, se puede convertir implícitamente en un puntero protegido "totalmente" como se muestra en el ejemplo del 2do código, así que a continuación se compila el código.

void f1(char const* const* a){} void f2(const char* b){} int main(int argc, char const *argv[]) { char* c; f1(&c); // works now too! f2(c); // works return 0; }

En realidad, hay un montón de preguntas y respuestas sobre este asunto por ahí. P.ej:

  1. conversión inválida de ''char **'' a ''const char **''
  2. ¿Por qué aparece un error al convertir un ''float **'' a ''const float **''?

EDITAR: Tengo el primer ejemplo mal por un poco. Gracias por señalarlo!