[dcl.meaning.general] # 9 Declarations [[dcl]](./#dcl) ## 9.3 Declarators [[dcl.decl]](dcl.decl#dcl.meaning.general) ### 9.3.4 Meaning of declarators [[dcl.meaning]](dcl.meaning#general) #### 9.3.4.1 General [dcl.meaning.general] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L2782) A declarator contains exactly one [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]"); it names the entity that is declared[.](#1.sentence-1) If the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") occurring in a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") is a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]"), the declarator shall appear in the [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") of a[*template-declaration*](temp.pre#nt:template-declaration "13.1 Preamble [temp.pre]") ([[temp.decls]](temp.decls "13.7 Template declarations")),[*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[*explicit-instantiation*](temp.explicit#nt:explicit-instantiation "13.9.3 Explicit instantiation [temp.explicit]") ([[temp.explicit]](temp.explicit "13.9.3 Explicit instantiation"))[.](#1.sentence-2) [*Note [1](#note-1)*: An [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") that is not an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") is used to declare certain functions ([[class.conv.fct]](class.conv.fct "11.4.8.3 Conversion functions"), [[class.dtor]](class.dtor "11.4.7 Destructors"), [[over.oper]](over.oper "12.4 Overloaded operators"), [[over.literal]](over.literal "12.6 User-defined literals"))[.](#1.sentence-3) — *end note*] The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") following a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") appertains to the entity that is declared[.](#1.sentence-4) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L2799) If the declaration is a friend declaration: - [(2.1)](#2.1) The [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") does not bind a name[.](#2.1.sentence-1) - [(2.2)](#2.2) If the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") E in the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") of the [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") or a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]"): * [(2.2.1)](#2.2.1) If the friend declaration is not a template declaration, then in the lookup for the terminal name of E: + [(2.2.1.1)](#2.2.1.1) if the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") in E is a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]"), all function declarations are discarded; + [(2.2.1.2)](#2.2.1.2) otherwise, if the [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") corresponds ([[basic.scope.scope]](basic.scope.scope "6.4.1 General")) to any declaration found of a non-template function, all function template declarations are discarded; + [(2.2.1.3)](#2.2.1.3) each remaining function template is replaced with the specialization chosen by deduction from the friend declaration ([[temp.deduct.decl]](temp.deduct.decl "13.10.3.7 Deducing template arguments from a function declaration")) or discarded if deduction fails[.](#2.2.1.sentence-1) * [(2.2.2)](#2.2.2) The [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") shall correspond to one or more declarations found by the lookup; they shall all have the same target scope, and the target scope of the [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") is that scope[.](#2.2.2.sentence-1) - [(2.3)](#2.3) Otherwise, the terminal name of E is not looked up[.](#2.3.sentence-1) The declaration's target scope is the innermost enclosing namespace scope; if the declaration is contained by a block scope, the declaration shall correspond to a reachable ([[module.reach]](module.reach "10.7 Reachability")) declaration that inhabits the innermost block scope[.](#2.3.sentence-2) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L2840) Otherwise: - [(3.1)](#3.1) If the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") in the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") of the [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") is a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Q, let S be its lookup context ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup")); the declaration shall inhabit a namespace scope[.](#3.1.sentence-1) - [(3.2)](#3.2) Otherwise, let S be the entity associated with the scope inhabited by the [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]")[.](#3.2.sentence-1) - [(3.3)](#3.3) If the [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") declares an explicit instantiation or a partial or explicit specialization, the [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") does not bind a name[.](#3.3.sentence-1) If it declares a class member, the terminal name of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") is not looked up; otherwise, only those lookup results that are nominable in S are considered when identifying any function template specialization being declared ([[temp.deduct.decl]](temp.deduct.decl "13.10.3.7 Deducing template arguments from a function declaration"))[.](#3.3.sentence-2) [*Example [1](#example-1)*: namespace N {inline namespace O {template void f(T); // #1template void g(T) {}}namespace P {template void f(T*); // #2, more specialized than #1template int g; }using P::f,P::g;}template<> void N::f(int*) {} // OK, #2 is not nominabletemplate void N::g(int); // error: lookup is ambiguous — *end example*] - [(3.4)](#3.4) Otherwise, the terminal name of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") is not looked up[.](#3.4.sentence-1) If it is a qualified name, the [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") shall correspond to one or more declarations nominable in S; all the declarations shall have the same target scope and the target scope of the [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") is that scope[.](#3.4.sentence-2) [*Example [2](#example-2)*: namespace Q {namespace V {void f(); }void V::f() { /* ... */ } // OKvoid V::g() { /* ... */ } // error: g() is not yet a member of Vnamespace V {void g(); }}namespace R {void Q::V::g() { /* ... */ } // error: R doesn't enclose Q} — *end example*] - [(3.5)](#3.5) If the declaration inhabits a block scope S and declares a function ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) or uses the extern specifier, the declaration shall not be attached to a named module ([[module.unit]](module.unit "10.1 Module units and purviews")); its target scope is the innermost enclosing namespace scope, but the name is bound in S[.](#3.5.sentence-1) [*Example [3](#example-3)*: namespace X {void p() { q(); // error: q not yet declaredextern void q(); // q is a member of namespace Xextern void r(); // r is a member of namespace X}void middle() { q(); // error: q not found}void q() { /* ... */ } // definition of X​::​q}void q() { /* ... */ } // some other, unrelated qvoid X::r() { /* ... */ } // error: r cannot be declared by [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") — *end example*] [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L2932) Astatic,thread_local,extern,mutable,friend,inline,virtual,constexpr,consteval,constinit, ortypedef specifier or an [*explicit-specifier*](dcl.fct.spec#nt:explicit-specifier "9.2.3 Function specifiers [dcl.fct.spec]") applies directly to each [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in a declaration; the type specified for each [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") depends on both the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]") and its [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]")[.](#4.sentence-1) [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L2953) Thus, (for each [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]")) a declaration has the formT D whereT is of the form [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt[*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]") andD is a declarator[.](#5.sentence-1) Following is a recursive procedure for determining the type specified for the contained[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") by such a declaration[.](#5.sentence-2) [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L2970) First, the[*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]") determines a type[.](#6.sentence-1) In a declarationT D the[*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]")T determines the typeT[.](#6.sentence-2) [*Example [4](#example-4)*: In the declarationint unsigned i; the type specifiersintunsigned determine the type “unsigned int” ([[dcl.type.simple]](dcl.type.simple "9.2.9.3 Simple type specifiers"))[.](#6.sentence-3) — *end example*] [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L2995) In a declaration[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")optTD whereD is an unadorned [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]"), the type of the declared entity is “T”[.](#7.sentence-1) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3006) In a declarationTD whereD has the form ( D1 ) the type of the contained[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") is the same as that of the contained[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in the declarationT D1 Parentheses do not alter the type of the embedded[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]"), but they can alter the binding of complex declarators[.](#8.sentence-2)