Pregunta Declarando una variable con dos tipos: "int char"


Soy un principiante de C ++, y estoy leyendo Programación de Bjarne Stroustrup: Principios y práctica con C ++.

En la sección de 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 implican 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 idiomas con los que estoy relativamente familiarizado). ¿Es esto un error tipográfico o una sintaxis C ++ válida?


75
2017-07-09 06:53


origen


Respuestas:


Es un error en el libro. Esa no es una declaración de C ++ válida, incluso sin la supuesta reducción de la conversión.

No se menciona en ninguna de las erratas en La página de Bjarne Stroustrup(4ª impresión y antes), sin embargo, que es impar. Es un error bastante claro. Imagino que se comenta con //error pocas personas notan el error en la declaración en sí.


91
2017-07-09 06:56



El libro está mal.

La secuencia de fichas int char b1{1000}; no es semánticamente válido C ++.

Estás tratando de declarar b1 con más de un tipo, lo cual no tiene sentido.


22
2017-07-09 06:55



Está mal. En C / C ++ las declaraciones de tipo múltiple 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 .c y .i son solo identificadores por tipo con el mismo valor.


10
2017-07-10 06:41



Esto está mal en la sintaxis C / C ++. En adición a unions (ver @ respuesta Alex), hay una forma en C ++ para almacenar solo uno de los tipos viables llamados std::variant (unión segura de tipo):

#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
}

6
2017-07-13 08:24