The clause you quote, 7.2/5, describes the types of the enumerators. But the enumerators only form part of the definition of the enumeration. The underlying type of the enumeration is large enough to hold the values all enumerators, subject to 7.2/6:
It is implementation-defined which integral type is used as the underlying type except that the underlying type shall not be larger than int
unless the value of an enumerator cannot fit in an int
or unsigned int
.
So it is guaranteed that your underlying type is no larger than int
(since int
can represent 0, 1 and 2). It is true that the type of your first enumerator is char
inside the enum definition, but all actual enum values are of type A
. To actually control the underlying type, use the enum-base syntax (e.g. enum A : char
), and to query it you can use the std::underlying_type
trait.
If you actually would like to see the effect of the enumerator's type in the definition, you can try something like this:
enum Foo { a = '\010', b = sizeof(a) };
std::cout << typeid(b).name() << "\n"; // some variant of "Foo"
std::cout << b << "\n"; // "1"
std::cout << sizeof(b) << "\n"; // implementation-defined, not greater
// than sizeof(int)