Bonjour,
Comme vous le savez, bien mieux que moi, il existe différentes façons pour initialiser une variable. Entre autres, int a(0); int a = 0; int a{0}...Ma question, quelle est celle que je dois privilégier?
Merci et bonne après-midi
Bonjour,
Comme vous le savez, bien mieux que moi, il existe différentes façons pour initialiser une variable. Entre autres, int a(0); int a = 0; int a{0}...Ma question, quelle est celle que je dois privilégier?
Merci et bonne après-midi
Bonjour,
Dans le cas d'un type de base que l'on initialise avec une valeur de même type, les 4 initialisations sont équivalentes
On pourrait aussi utiliser auto à la place de int dans le code précédent.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 int i1 = 1; // initialisation par copie int i2{2}; // initialisation directe (car 2 et i2 ont le même type) int i3(3); // initialisation directe int i4 = {4}; // initialisation par liste copie // j'en ajoute deux autres pratiques à connaître pour des types complexes à écrire auto i5 = int{5}; // équiv à i2 auto i6 = int(6); // équiv à i3
Si une conversion est nécessaire et nécessite une conversion restrictive, les initialisations avec {} ne passeront pas
Si le type destination nécessite une conversion explicite, ce sont les initialisations avec = qui ne passeront pas
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 int c1 = 1.5; // au mieux un warning //int c2{2.5}; erreur conversion par liste directe restrictive int c3(3.5); // au mieux un warning //int c4 = {4.5}; erreur conversion par liste copie restrictive
Et donc si à la fois la conversion est explicite et nécessite une conversion restrictive, seule l'initialisation avec les parenthèses est acceptée. C'est celle qui va prendre tous les risques...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 struct EInt { explicit EInt( int x ) {} }; //EInt E1 = 1; erreur conversion impossible EInt E2{2}; EInt E3(3); //EInt E4 = {4}; erreur conversion impossible
Alors, laquelle préférer? Celle qui nous donne le plus de garanties de ne pas faire n'importe quoi. Donc la quatrième avec = et {}.
Mais attention, s'il existe ces quatre manières d'initialiser, c'est que parfois elles se distinguent et, il faut alors utiliser la bonne.
Ici on ne s'est intéressé qu'au cas où l'initialisation demandait un unique paramètre. S'il y en a 0 ou bien plusieurs, l'utilisation des {} est aussi celle à préférer.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 std::vector<int> v1{4}; // un tableau d'un élément qui vaut 4 std::vector<int> v2(4); // un tableau de 4 éléments tous nuls std::vector<int> v3 = 4; // ne compile pas
Un grand merci pour cette magistrale réponse!
Je vous souhaite une année 2024 constellée de surprises agréables et remplie de rendez-vous avec le bonheur et le succès
Jean-Pierre
J'avais fait un tableau sur un autre forum qui montre les différentes formes d'initialisations possible. Depuis C++20 et la possibilité d'initialiser les membres d'une structure sans avoir de constructeur, les différences en faveur de {} sont la conversion avec perte qui donne une erreur de compilation, les initialisations désignées, le MVP (Most Vexing Parse) qui n'existe pas. Dans le comportement qui diffère, il y a le traitement de std::initializer_list dans les constructeurs.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager