cpp/language/enum

An enumeration is a distinct type whose value is restricted to a range of values (see below for details), 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. An enumeration has the same, , and as its underlying type. Furthermore, each value of an enumeration has the same representation as the corresponding value of the underlying type.

An enumeration is (re)declared using the following syntax:

@1@ enum-specifier, which appears in of the  syntax: defines the enumeration type and its enumerators. @2@ A trailing comma can follow the. @3@ Opaque enum declaration: defines the enumeration type but not its enumerators: after this declaration, the type is a complete type and its size is known.

There are two distinct kinds of enumerations: unscoped enumeration (declared with the ) and scoped enumeration (declared with the   or ).

Unscoped enumerations
@1@ Declares an unscoped enumeration type whose underlying type is not fixed (in this case, the underlying type is an implementation-defined integral type that can represent all enumerator values; this type is not larger than unless the value of an enumerator cannot fit in an  or . If the  is empty, the underlying type is as if the enumeration had a single enumerator with value 0. If no integral type can represent all the enumerator values, the enumeration is ill-formed). @2@ Declares an unscoped enumeration type whose underlying type is fixed. @3@ Opaque enum declaration for an unscoped enumeration must specify the name and the underlying type.

Each becomes a named constant of the enumeration's type (that is, ), 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, 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.

Values of unscoped enumeration type are to integral types. If the underlying type is not fixed, the value is convertible to the first type from the following list able to hold their entire value range:, , , ,. If the underlying type is fixed, the values can be converted to their underlying type (preferred in ), which can then be.

Values of integer, floating-point, and enumeration types can be converted by or, to any enumeration type. If the underlying type is not fixed and the source value is out of range, the behavior is undefined. (The source value, as converted to the enumeration's underlying type if floating-point, is in range if it would fit in the smallest large enough to hold all enumerators of the target enumeration.) Otherwise, the result is the same as the result of  to the underlying type.

Note that the value after such conversion may not necessarily equal any of the named enumerators defined for the enumeration.

The of an unscoped enumeration may be omitted: such declaration only introduces the enumerators into the enclosing scope:

When an unscoped enumeration is a class member, its enumerators may be accessed using class member access operators and :

Scoped enumerations
{{rrev|since=c++20|

Using-enum-declaration
must name a non- enumeration type. The enumeration declarations are found by ordinary or  lookup, depending on whether  is present.

A using-enum-declaration introduces the enumerator names of the named enumeration as if by a for each enumerator. When in class scope, a using-enum-declaration adds the enumerators of the named enumeration as members to the scope, making them accessible for member lookup.

Two using-enum-declarations that introduce two enumerators of the same name conflict.

}}