[dcl.type.elab]

# 9 Declarations [[dcl]](./#dcl)

## 9.2 Specifiers [[dcl.spec]](dcl.spec#dcl.type.elab)

### 9.2.9 Type specifiers [[dcl.type]](dcl.type#elab)

#### 9.2.9.5 Elaborated type specifiers [dcl.type.elab]

[elaborated-type-specifier:](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]")  
[*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")  
[*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")  
[*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") templateopt [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")  
enum [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L1579)

The component names of an [*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") are
its [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") (if any) and
those of its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") and[*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") (if any)[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L1586)

If an [*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") is the sole constituent of a
declaration, the declaration is ill-formed unless it is an explicit
specialization ([[temp.expl.spec]](temp.expl.spec "13.9.4 Explicit specialization")),
a partial specialization ([[temp.spec.partial]](temp.spec.partial "13.7.6 Partial specialization")),
an explicit
instantiation ([[temp.explicit]](temp.explicit "13.9.3 Explicit instantiation")), or it has one of the following
forms:

[*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") ;  
[*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") ;

In the first case,
the [*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") declares
the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") as a [*class-name*](class.pre#nt:class-name "11.1 Preamble [class.pre]")[.](#2.sentence-2)

The second case shall appear only
in an [*explicit-specialization*](temp.expl.spec#nt:explicit-specialization "13.9.4 Explicit specialization [temp.expl.spec]") ([[temp.expl.spec]](temp.expl.spec "13.9.4 Explicit specialization")) or
in a [*template-declaration*](temp.pre#nt:template-declaration "13.1 Preamble [temp.pre]") (where it declares a partial specialization)[.](#2.sentence-3)

The [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]"), if any, appertains
to the class or template being declared[.](#2.sentence-4)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L1611)

Otherwise, an [*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") E shall not have
an [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#3.sentence-1)

If E contains an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") but no [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") and
(unqualified) lookup for the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") finds nothing,E shall not be introduced by the enum keyword and
declares the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") as a [*class-name*](class.pre#nt:class-name "11.1 Preamble [class.pre]")[.](#3.sentence-2)

The target scope of E is the nearest enclosing namespace or block scope[.](#3.sentence-3)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L1621)

A [*friend-type-specifier*](class.mem.general#nt:friend-type-specifier "11.4.1 General [class.mem.general]") that is an [*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") shall have one of the following forms:

[*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")  
[*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")  
[*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") templateopt [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")

Any unqualified lookup for the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") (in the first case)
does not consider scopes that contain
the nearest enclosing namespace or block scope; no name is bound[.](#4.sentence-1)

[*Note [1](#note-1)*:

A [*using-directive*](namespace.udir#nt:using-directive "9.9.4 Using namespace directive [namespace.udir]") in the target scope is ignored
if it refers to a namespace not contained by that scope[.](#4.sentence-2)

â *end note*]

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L1638)

[*Note [2](#note-2)*:

[[basic.lookup.elab]](basic.lookup.elab "6.5.6 Elaborated type specifiers") describes how name lookup proceeds
in an [*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]")[.](#5.sentence-1)

An [*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") can be used to refer to
a previously declared [*class-name*](class.pre#nt:class-name "11.1 Preamble [class.pre]") or [*enum-name*](dcl.enum#nt:enum-name "9.8.1 Enumeration declarations [dcl.enum]") even if the name has been hidden by a non-type declaration[.](#5.sentence-2)

â *end note*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L1647)

If the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") or [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") in an [*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") resolves to a [*class-name*](class.pre#nt:class-name "11.1 Preamble [class.pre]") or[*enum-name*](dcl.enum#nt:enum-name "9.8.1 Enumeration declarations [dcl.enum]"), the [*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") introduces it into the declaration the same way a[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") introduces
its [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") ([[dcl.type.simple]](dcl.type.simple "9.2.9.3 Simple type specifiers"))[.](#6.sentence-1)

If the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") or [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") resolves to a[*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") ([[dcl.typedef]](dcl.typedef "9.2.4 The typedef specifier"), [[temp.names]](temp.names "13.3 Names of template specializations")),
the [*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") is ill-formed[.](#6.sentence-2)

[*Note [3](#note-3)*:

This implies that, within a class template with a template[*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]") T, the declarationfriend class T; is ill-formed[.](#6.sentence-3)

However, the similar declaration friend T; is well-formed ([[class.friend]](class.friend "11.8.4 Friends"))[.](#6.sentence-4)

â *end note*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L1667)

The [*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") or enum keyword
present in an[*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") shall agree in kind with the
declaration to which the name in the[*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") refers[.](#7.sentence-1)

This rule also applies to
the form of [*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") that declares a[*class-name*](class.pre#nt:class-name "11.1 Preamble [class.pre]") or friend class since it can be construed
as referring to the definition of the class[.](#7.sentence-2)

Thus, in any[*elaborated-type-specifier*](#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]"), the enum keyword
shall be
used to refer to an enumeration ([[dcl.enum]](dcl.enum "9.8.1 Enumeration declarations")), the union[*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") shall be used to refer to a union ([[class.union]](class.union "11.5 Unions")),
and either the class or struct[*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") shall be used to refer to a non-union class ([[class.pre]](class.pre "11.1 Preamble"))[.](#7.sentence-3)

[*Example [1](#example-1)*: enum class E { a, b };enum E x = E::a; // OKstruct S { } s;class S* p = &s; // OK â *end example*]
