Belloc
Belloc

Reputation: 6390

Trying to understand §7.2/6 in C++14

7.2/6 (C++14):

An enumeration whose underlying type is fixed is an incomplete type from its point of declaration (3.3.2) to immediately after its enum-base (if any), at which point it becomes a complete type. An enumeration whose underlying type is not fixed is an incomplete type from its point of declaration to immediately after the closing } of its enum-specifier, at which point it becomes a complete type.

Take a look at the snippet below (see live example):

enum A{} t;                 // enum A{} is a complete type (OK)
enum class B:int z;         // enum class B:int is not a complete type
int main()
{
}

I understand why B is not a complete type. But, by just looking at the paragraph above, this doesn't seem so clear to me. z is declared right after the enum-base of an enumeration, whose underlying type is fixed, the same way tis declared right after the closing } of the enum-specifier of an enumerator whose underlying type is not fixed.

Upvotes: 2

Views: 116

Answers (1)

T.C.
T.C.

Reputation: 137310

The problem isn't that B isn't complete. As shown in your own quote, it is complete immediately after its enum-base, : int. The problem is that you are using a construct that the grammar doesn't allow.

The type-specifier production allows two ways in which the keyword enum can appear in it ([dcl.type]):

  1. in an elaborated-type-specifier.
  2. in an enum-specifier.

An elaborated-type-specifier containing enum looks like ([dcl.type.elab])

enum nested-name-specifieropt identifier

which doesn't fit your code, and moreover cannot declare a new type (see [basic.lookup.elab]/p2). That is, while struct A* pa; is legal even without a previous declaration of A, enum B * pb; is not legal.

An enum-specifier ([dcl.enum]/p1) is one of

enum-head { enumerator-listopt }
enum-head { enumerator-list , }

without digging into what enum-head is, it is obvious this requires braces, which isn't in your code.

enum class B : int; is an opaque-enum-declaration, whose grammar is

enum-key attribute-specifier-seqopt identifier enum-baseopt ;

This doesn't allow you to declare anything other than the enum itself.

In short, the grammar simply doesn't allow enum class B:int z;. Instead, you can write enum class B:int; B z;, which is perfectly valid, though the : int is redundant.

Upvotes: 2

Related Questions