Les types d'énumération C ++ semblent être "constructibles par défaut":

enum UE { a=1, b, c };
enum class SE { a=1, b, c };

int main() {
    UE ue;
    SE se;
}

Comment cela peut-il être expliqué à partir de la norme?

Je veux dire - disons que nous voulions changer la norme pour qu'elle ne soit pas constructible par défaut. Quelles clauses changeraient?

3
Andrew Tomazos 27 janv. 2019 à 17:30

3 réponses

Meilleure réponse

Tout est dans [dcl.init] / 7:

Initialiser par défaut un objet de type T signifie:

  • Si T est un type de classe (éventuellement qualifié cv), les constructeurs sont considérés. Les constructeurs applicables sont énumérés ([over.match.ctor]), et le meilleur pour l'initialiseur () est choisi grâce à la résolution de surcharge. Le constructeur ainsi sélectionné est appelé, avec une liste d'arguments vide, pour initialiser l'objet.

  • Si T est un type de tableau, chaque élément est initialisé par défaut.

  • Sinon, aucune initialisation n'est effectuée.

UE et SE correspondent à la troisième puce, comme les types fondamentaux. Donc, l'initialisation est simplement un no-op, et ils se retrouvent avec une valeur indéterminée.

C'est également la liste à puces à laquelle vous devez vous attaquer en premier pour que les énumérations ne soient pas initialisables par défaut.

7
StoryTeller - Unslander Monica 27 janv. 2019 à 14:54

Ne laissez pas le class dans enum class vous confondre: il est toujours considéré comme un type non-classe. La syntaxe des énumérations de portée se trouve juste à coopter le mot-clé class, afin de ne pas ajouter encore un autre mot réservé à la langue.

2
Christoph Lipka 27 janv. 2019 à 19:05

Il existe un projet de spécification ici: http: / /www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4778.pdf

Voir section 9.6, Déclarations d'énumération.

Je pense que vous venez peut-être de Java, où les énumérations sont des classes. En C ++, les valeurs énumérées ne sont que des constantes entières. Le type de la constante est généralement int bien qu'il puisse être défini explicitement.

Puisque l'énumération est juste un int, lorsque vous en déclarez un sans initialiseur, aucun constructeur par défaut n'est impliqué; vous obtenez juste un int non initialisé.

1
Willis Blackburn 27 janv. 2019 à 14:46