W C++11 wprowadzono mechanizm 'scoped enums' — słowo kluczowe enum class.
Główne różnice w porównaniu do klasycznych enum:
enum class MyE : uint8_t { ... };).Po co to potrzebne: Aby zwiększyć bezpieczeństwo typów, zapobiegać konfliktom nazw, błędnym porównaniom oraz jawnie zarządzać przechowywaniem.
Przykład:
enum Color { Red, Green }; Color c = Red; // Zwykły enum, Red jest widoczny globalnie enum class State { Off, On }; State s = State::On; // Należy wskazać State::On
Nie można pisać:
enum class State { Off, On }; int x = State::On; // Błąd! Tylko z rzutowaniem int y = static_cast<int>(State::Off); // OK
Dlaczego nie można wykonać porównania logicznego między wartościami różnych enum class, nawet jeśli mają tę samą nazwę i typ?
Odpowiedź:
Bezpieczeństwo typów: każda enum class to oddzielny typ, nawet jeśli typ podstawowy jest taki sam, a enumeratory mają tę samą nazwę. Kompilator uzna je za różne typy i nie dopuści do niejawnego porównania.
Historia
Przechodząc z enum na enum class w projekcie zarządzania maszynami, zapomniano dodać jawne rzutowanie podczas wyświetlania wartości w logu. Logi zaczęły pokazywać „obce” wartości (nie rozpoznawano State::On jako liczby), co skomplikowało debugowanie.
Historia
W serwisie REST po migracji zwykłego enum na enum class kod porównywał wartości różnych enumeracji z różnych enum class. Kompilator nie dopuszczał tego, automatyczne testy przestały się kompilować.
Historia
W systemie audytu programiści mylili stary i nowy składnik — czasami przypadkowo ogłaszali enum class, ale używali enumeratorów bez kwalifikatora, w rezultacie kompilował się nie ten kod lub występowały błędy linkowania z powodu kolidujących nazw.