Introduction
An enumeration is a distinct type whose value is restricted to a range of values, which may include several explicitly named constants (“enumerators”). The values of the constants are values of an integral type known as the underlying type of the enumeration. There are two distinct kinds of enumerations: unscoped enumeration (declared with the enum-key enum) and scoped enumeration (declared with the enum-key enum class or enum struct).
Unscoped enumeration
Below are syntax for unscoped enumeration
enum name { enumerator = constexpr , enumerator = constexpr , ... } // 1 enum name : type { enumerator = constexpr , enumerator = constexpr , ... } // 2
- Declares an unscoped enumeration type whose underlying type is not fixed (in this case, the underlying type is an implementation-defined integral type
- Declares an unscoped enumeration type whose underlying type is fixed.
Each enumerator becomes a named constant of the enumeration’s type (that is, name), visible in the enclosing scope, and can be used whenever constants are required. Each enumerator is associated with a value of the underlying type. When initializers are provided in the enumerator-list, the values of enumerators are defined by those initializers. If the first enumerator does not have an initializer, the associated value is zero. For any other enumerator whose definition does not have an initializer, the associated value is the value of the previous enumerator plus one.
enum Color { red, green, blue }; Color r = red; switch(r){ case red : std::cout << "red\n"; break; case green: std::cout << "green\n"; break; }
Values of integer, floating-point, and enumeration types can be converted by static_cast
or explicit cast, to any enumeration type. If the underlying type is not fixed and the source value is out of range, the result is unspecified .Note that the value after such conversion may not necessarily equal any of the named enumerators defined for the enumeration.
Scoped enumerations
Below are syntax for scoped enumeration
enum struct|class name { enumerator = constexpr , enumerator = constexpr , ... } // 1 enum struct|class name : type { enumerator = constexpr , enumerator = constexpr , ... } // 2
- Declares a scoped enumeration type whose underlying type is int (the keywords class and struct are exactly equivalent)
- Declares a scoped enumeration type whose underlying type is type
Each enumerator becomes a named constant of the enumeration’s type (that is, name), which is contained within the scope of the enumeration, and can be accessed using scope resolution operator. There are no implicit conversions from the values of a scoped enumerator to integral types, although static_cast may be used to obtain the numeric value of the enumerator.
enum class Color { red, green = 20, blue }; Color r = Color::blue; switch(r) { case Color::red : std::cout << "red\n"; break; case Color::green: std::cout << "green\n"; break; case Color::blue : std::cout << "blue\n"; break; } // int n = r; // error: no scoped enum to int conversion int n = static_cast<int>(r); // OK, n = 21
Enum with type specified
// Altitude may be altitude::high or altitude::low enum class altitude: char { high='h', low='l', // C++11 allows the extra comma };