Type of enumerator in the declaration of its enumeration

In C ++, in particular in C ++ 14 n4296, there are two paragraphs talking about the type of enumerator, which seems to contradict me. See 7.2 / 5 (this is 10.2 / 5 in n4659 ):

Each enumeration defines a type different from all other types. Each enumeration also has a base type. The main type can be explicitly specified using the enum base. For a type of an enumerated enumeration region, the base type is int if it is not explicitly specified. In both cases, the main type is called fixed. After closing the brackets of the enumeration qualifier, each enumerator has the type of its enumeration. If the base type is corrected, the type of each enumerator before the closing bracket is the base type , and the constant expression in the enumeration definition must be a converted constant expression of the base type [...]

And 5.1.1 / 11 (this is 8.1.4.2/4 in n4659 ) writes:

The nested qualifier name, which denotes enumeration (7.2), followed by the enumerator name of this enumeration, is a qualified identifier that refers to a counter. The result is an enumerator. The result type is an enumeration type. The result is a prvalue.

Then, what happens when we refer to an enumerator through a nested qualifier before closing the declaration bracket? Take, for example, the following snippet:

 template < typename T1, typename T2 > struct fail_if_not_same { static_assert(std::is_same<T1, T2>::value, "Fail!"); static constexpr int value = 0; }; enum class E : short { A, B = A + 1, C = fail_if_not_same<decltype(B), short>::value, D = fail_if_not_same<decltype(E::B), short>::value }; 

What is the type of expression E::B above? Is this a contradiction in the standard? Both gcc and clang follow 7.2 / 5.

+6
source share
1 answer

I think that the standard contradicts itself, as in 5.1.1 / 11

As a result, a counter appears. (one)

and

Result type - enumeration type. (2)

If (1) is true, then the result type must be the type of the enumerator, which, according to 7.2 / 5, is either the base type of the enumeration or the type defined by the enumeration, depending on whether or after the closing parenthesis.

Suppose your sample code should compile because E::B is B and type B is short .

Now, if you take into account (2), this will not change anything after closing. But if (2) is true before the closing bracket, it means that the type E::B is equal to E , and at the same time, the type B is short , so you get E::B != B , which contradicts (1).

+3
source

Source: https://habr.com/ru/post/1015149/


All Articles