In C++11, the 'scoped enums' mechanism was introduced — the keyword enum class.
Main differences from classic enums:
enum class MyE : uint8_t { ... };).Why is it needed: To enhance type safety, prevent naming conflicts, erroneous comparisons, and provide explicit control over storage.
Example:
enum Color { Red, Green }; Color c = Red; // Regular enum, Red is globally visible enum class State { Off, On }; State s = State::On; // Need to specify State::On
You cannot write:
enum class State { Off, On }; int x = State::On; // Error! Only with a cast int y = static_cast<int>(State::Off); // OK
Why can’t you perform a logical comparison between values of different enum classes, even if they have the same names and underlying types?
Answer:
Type safety: each enum class is a separate type, even if the underlying type is the same and the enumerators match in name. The compiler will treat them as different types and will not allow implicit comparisons.
Story
When transitioning from enum to enum class in a machine control project, they forgot to add explicit casting when logging values. Logs began to show "foreign" values (did not recognize State::On as a number), complicating debugging.
Story
In a REST service, after migrating from a regular enum to an enum class, the code compared values of different enumerations from different enum classes. The compiler did not allow this, and automated tests stopped building.
Story
In an auditing system, developers confused the old and new syntax — sometimes accidentally declaring enum class, but using enumerators without qualification, resulting in the wrong code compiling or linkage errors due to name collisions.