Soy un principiante de C ++ y estoy leyendo Programación de Bjarne Stroustrup: Principios y práctica con C ++ .
En la sección sobre 3.9.2 Conversiones inseguras , el autor mencionó
Cuando el inicializador es un literal entero, el compilador puede verificar el valor real y aceptar valores que no impliquen un estrechamiento:
int char b1 {1000}; // error: narrowing (assuming 8-bit chars)
Estoy desconcertado por esta declaración. Utiliza dos tipos ( int
y char
). Nunca antes había visto tal declaración en Java y Swift (los dos lenguajes con los que estoy relativamente familiarizado). ¿Es esto un error tipográfico o una sintaxis válida de C ++?
float char
otro tipo útil, especialmente en piscinas. Algunos vienen con un soporte para una cerveza.Respuestas:
Es un error del libro. Esa no es una declaración válida de C ++, incluso sin la supuesta conversión de restricción.
Sin embargo, no se menciona en ninguna de las erratas en la página de Bjarne Stroustrup (cuarta impresión y anteriores), lo cual es extraño. Es un error bastante claro. Me imagino que como está comentado
//error
pocas personas notan el error en la propia declaración.fuente
char b1 {1000};
(porque eso provocaría el error mencionado en el comentario). Supongo que los dedos de Bjarne estaban cansados ese día.int
allí! :-)El libro está mal.
La secuencia de tokens
int char b1{1000};
no es C ++ semánticamente válida.Está intentando declarar
b1
con más de un tipo, lo que no tiene sentido.fuente
Está mal. En C / C ++, las declaraciones de varios tipos se pueden lograr mediante el uso de uniones. P.ej:
union { int i; char c; } var; var.i = 42; /* OR */ var.c = ‘c’;
El almacenamiento es el mismo, por lo que .cy .i son identificadores por tipo con el mismo valor.
fuente
Esto está mal en la sintaxis de C / C ++. Además de
union
s (consulte la respuesta de @Alex), hay una forma en C ++ de almacenar solo uno de los tipos disponibles llamadostd::variant
(unión segura de tipos ):#include <variant> #include <string> int main() { std::variant<int, float> v, w; v = 12; // v contains int int i = std::get<int>(v); w = std::get<int>(v); w = std::get<0>(v); // same effect as the previous line w = v; // same effect as the previous line // std::get<double>(v); // error: no double in [int, float] // std::get<3>(v); // error: valid index values are 0 and 1 try { std::get<float>(w); // w contains int, not float: will throw } catch (std::bad_variant_access&) {} std::variant<std::string> v("abc"); // converting constructors work when unambiguous v = "def"; // converting assignment also works when unambiguous }
fuente