10 Declarations [dcl.dcl]

10.1 Specifiers [dcl.spec]

10.1.7 Type specifiers [dcl.type]

10.1.7.3 Elaborated type specifiers [dcl.type.elab]

elaborated-type-specifier:
	class-key attribute-specifier-seqopt nested-name-specifieropt identifier
	class-key simple-template-id
	class-key nested-name-specifier templateopt simple-template-id
	enum nested-name-specifieropt identifier

An attribute-specifier-seq shall not appear in an elaborated-type-specifier unless the latter is the sole constituent of a declaration. If an elaborated-type-specifier is the sole constituent of a declaration, the declaration is ill-formed unless it is an explicit specialization, an explicit instantiation or it has one of the following forms:

class-key attribute-specifier-seqopt identifier ;
friend class-key ::opt identifier ;
friend class-key ::opt simple-template-id ;
friend class-key nested-name-specifier identifier ;
friend class-key nested-name-specifier templateopt simple-template-id ;

In the first case, the attribute-specifier-seq, if any, appertains to the class being declared; the attributes in the attribute-specifier-seq are thereafter considered attributes of the class whenever it is named.

[basic.lookup.elab] describes how name lookup proceeds for the identifier in an elaborated-type-specifier. If the identifier resolves to a class-name or enum-name, the elaborated-type-specifier introduces it into the declaration the same way a simple-type-specifier introduces its type-name. If the identifier resolves to a typedef-name or the simple-template-id resolves to an alias template specialization, the elaborated-type-specifier is ill-formed. [Note: This implies that, within a class template with a template type-parameter T, the declaration

friend class T;

is ill-formed. However, the similar declaration friend T; is allowed ([class.friend]). end note]

The class-key or enum keyword present in the elaborated-type-specifier shall agree in kind with the declaration to which the name in the elaborated-type-specifier refers. This rule also applies to the form of elaborated-type-specifier that declares a class-name or friend class since it can be construed as referring to the definition of the class. Thus, in any elaborated-type-specifier, the enum keyword shall be used to refer to an enumeration, the union class-key shall be used to refer to a union, and either the class or struct class-key shall be used to refer to a class declared using the class or struct class-key. [Example:

enum class E { a, b };
enum E x = E::a;                // OK

end example]