In C++11 wurde der Mechanismus 'scoped enums' — das Schlüsselwort enum class — eingeführt.
Hauptunterschiede zu klassischen enums:
enum class MyE : uint8_t { ... };).Warum ist das notwendig: Um die Typensicherheit zu erhöhen, Namenskonflikte zu verhindern, fehlerhafte Vergleiche zu vermeiden und die Speicherung explizit zu steuern.
Beispiel:
enum Color { Red, Green }; Color c = Red; // Gewöhnliches enum, Red ist global sichtbar enum class State { Off, On }; State s = State::On; // Es muss State::On angegeben werden
Das kann man nicht schreiben:
enum class State { Off, On }; int x = State::On; // Fehler! Nur mit Casting int y = static_cast<int>(State::Off); // OK
Warum kann man keine logische Vergleich zwischen Werten verschiedener enum classes anstellen, selbst wenn sie gleiche Namen und den gleichen zugrunde liegenden Typ haben?
Antwort:
Typensicherheit: Jede enum class ist ein eigener Typ, selbst wenn der zugrunde liegende Typ derselbe ist und die Aufzählungswerte die gleichen Namen haben. Der Compiler betrachtet sie als verschiedene Typen und erlaubt keinen impliziten Vergleich.
Geschichte
Beim Übergang von enum zu enum class in einem Projekt zur Maschinensteuerung wurde vergessen, eine explizite Umwandlung beim Ausgeben von Werten ins Log hinzuzufügen. Die Logs begannen "fremde" Werte anzuzeigen (State::On wurde nicht als Zahl erkannt), was das Debuggen erschwerte.
Geschichte
In einem REST-Service verglich der Code nach der Migration von gewöhnlichen enums zu enum class Werte aus verschiedenen Aufzählungen von unterschiedlichen enum classes. Der Compiler ließ das nicht zu, die automatischen Tests konnten nicht mehr kompiliert werden.
Geschichte
Im Auditsystem verwechselten die Entwickler die alte und neue Syntax — manchmal erklärten sie versehentlich enum class, verwendeten aber die Enumerator ohne Qualifikator, was dazu führte, dass nicht der richtige Code kompiliert wurde oder Linker-Fehler aufgrund von Namenskonflikten auftraten.