Je suis un débutant en C++ et je lis Programmation de Bjarne Stroustrup: principes et pratique utilisant le C++.
Dans la section sur .9.2 Conversions non sécurisées, l’auteur a mentionné
Lorsque l'initialiseur est un littéral entier, le compilateur peut vérifier la valeur réelle et accepter les valeurs n'impliquant pas un rétrécissement:
int char b1 {1000}; // error: narrowing (assuming 8-bit chars)
Je suis perplexe par cette déclaration. Il utilise deux types (int
et char
). Je n'ai jamais vu une telle déclaration dans Java et Swift (les deux langages que je connais assez bien). Est-ce une faute de frappe ou une syntaxe C++ valide?
C'est une erreur dans le livre. Ce n'est pas une déclaration C++ valide, même sans la supposée conversion restrictive.
Cela n'est mentionné dans aucune des erratas sur page de Bjarne Stroustrup (4ème impression et antérieure), ce qui est étrange. C'est une erreur assez claire. J'imagine que c'est commenté avec //error
peu de gens remarquent l'erreur dans la déclaration elle-même.
Le livre est faux.
La séquence de jetons int char b1{1000};
n'est pas sémantiquement valide en C++.
Vous essayez de déclarer b1
avec plusieurs types, ce qui n’a aucun sens.
Il est faux. En C/C++, les déclarations multi-types peuvent être réalisées via l'utilisation de 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 ne sont que des poignées par type ayant la même valeur.
Ceci est faux dans la syntaxe C/C++. En plus de union
s (voir @Alex answer), il existe un moyen C++ de ne stocker qu'un seul des types disponibles appelé std::variant
(type-safe union):
_#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
}
_