81 votes

Déclarer une variable avec deux types: "int char"

Je suis une C++ débutant, et je suis en train de lire Bjarne Stroustrup de Programmation: Principes et Pratique avec C++.

Dans la section 3.9.2 Dangereux conversions, l'auteur mentionné

Lorsque l'initialisation est un entier littéral, le compilateur peut vérifier la valeur réelle et d'accepter des valeurs qui n'impliquent pas de rétrécissement:

int char b1 {1000};     // error: narrowing (assuming 8-bit chars)

Je suis intrigué par cette déclaration. Il utilise deux types (int et char). Je n'ai jamais vu une telle déclaration en Java et Swift avant (les deux langues, je suis relativement familier avec). Est-ce une faute de frappe ou un valide syntaxe C++?

95voto

StoryTeller Points 6139

C'est une erreur dans le livre. Ce n'est pas une déclaration C ++ valide, même sans la conversion de rétrécissement supposée.

Il n'est mentionné dans aucune des erratas de la page de Bjarne Stroustrup (4e impression et versions antérieures), ce qui est étrange. C'est une erreur assez claire. J'imagine puisque c'est commenté avec //error peu de gens remarquent l'erreur dans la déclaration elle-même.

24voto

Bathsheba Points 23209

Le livre est faux.

La séquence de jetons int char b1{1000}; n'est pas C ++ sémantiquement valide.

Vous essayez de déclarer b1 avec plusieurs types, ce qui n'a aucun sens.

10voto

Alex Points 86

Il est faux. En C / C ++, les déclarations multi-types peuvent être réalisées via l'utilisation d'unions. Par exemple:

 union {
    int i;
    char c;
} var;

var.i = 42;
/* OR */
var.c = ‘c';
 

Le stockage est le même, donc .c et .i sont juste des descripteurs par type à la même valeur.

6voto

val Points 355

C'est faux dans la syntaxe C / C ++. En plus de union s (voir la réponse @Alex), il existe un moyen C ++ de stocker un seul des types disponibles appelé std::variant (union de type sécurisé):

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X