ProgrammationDéveloppeur C++ Senior

Parlez de mécanisme 'enum class' (enums à portée) en C++. Quelle est sa différence par rapport aux énumérations traditionnelles et pourquoi a-t-il été introduit ? Quelles erreurs sont typiques lors du passage des anciennes enum aux enum class ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Le mécanisme 'scoped enums' a été introduit dans C++11 — le mot-clé enum class.

Principales différences par rapport aux enums traditionnels :

  • Le contenu de l'enum class a sa propre portée (scope), pas de contamination de l'espace de noms global.
  • Il n'y a pas de conversion implicite des énumérateurs en int (une conversion explicite est requise).
  • Le type d'une enum class par défaut est : int, mais on peut en spécifier un autre (par exemple, enum class MyE : uint8_t { ... };).

Pourquoi est-ce nécessaire : Pour améliorer la sécurité des types, prévenir les conflits de noms, les comparaisons erronées et gérer explicitement le stockage.

Exemple :

enum Color { Red, Green }; Color c = Red; // Enum traditionnel, Red est visible globalement enum class State { Off, On }; State s = State::On; // Doit spécifier State::On

On ne peut pas écrire :

enum class State { Off, On }; int x = State::On; // Erreur ! Seulement avec un cast int y = static_cast<int>(State::Off); // OK

Question piège

Pourquoi ne peut-on pas faire de comparaison logique entre les valeurs de différentes enum class, même si elles correspondent par leurs noms et leur type sous-jacent ?

Réponse :

Sécurité de type : chaque enum class est un type distinct, même si le type sous-jacent est le même et que les énumérateurs correspondent par leurs noms. Le compilateur les considérera comme des types différents et n'autorisera pas la comparaison implicite.

Exemples d'erreurs réelles en raison de l'ignorance des subtilités de ce sujet.


Histoire

En passant de enum à enum class dans un projet de gestion de machines, on a oublié d'ajouter la conversion explicite lors de l'affichage des valeurs dans les logs. Les logs ont commencé à montrer des valeurs "étrangères" (ne reconnaissant pas State::On comme un nombre), ce qui a compliqué le débogage.


Histoire

Dans un service REST, après la migration d'un enum traditionnel à un enum class, le code comparait des valeurs d'énumérations de différents enum class. Le compilateur n'a pas permis cela, et les tests automatiques ont cessé de se compiler.


Histoire

Dans un système d'audit, les développeurs confondaient l'ancienne et la nouvelle syntaxe — parfois ils déclaraient par accident un enum class, mais utilisaient les énumérateurs sans le qualificateur, entraînant la compilation du mauvais code ou des erreurs de liaison en raison de noms correspondants.