Files
2025-10-25 03:02:53 +03:00

186 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.1General[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.2Unqualified names[expr.prim.id.unqual]") occurring in a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") is a [*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]"),
the declarator shall appear in the [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") of a[*template-declaration*](temp.pre#nt:template-declaration "13.1Preamble[temp.pre]") ([[temp.decls]](temp.decls "13.7Template declarations")),[*explicit-specialization*](temp.expl.spec#nt:explicit-specialization "13.9.4Explicit specialization[temp.expl.spec]") ([[temp.expl.spec]](temp.expl.spec "13.9.4Explicit specialization")), or[*explicit-instantiation*](temp.explicit#nt:explicit-instantiation "13.9.3Explicit instantiation[temp.explicit]") ([[temp.explicit]](temp.explicit "13.9.3Explicit instantiation"))[.](#1.sentence-2)
[*Note [1](#note-1)*:
An [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") that is not an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is used to declare
certain functions ([[class.conv.fct]](class.conv.fct "11.4.8.3Conversion functions"), [[class.dtor]](class.dtor "11.4.7Destructors"), [[over.oper]](over.oper "12.4Overloaded operators"), [[over.literal]](over.literal "12.6User-defined literals"))[.](#1.sentence-3)
— *end note*]
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") following a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[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.1General[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.1General[expr.prim.id.general]") E in
the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") of the [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") is
a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") or a [*template-id*](temp.names#nt:template-id "13.3Names 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.2Unqualified names[expr.prim.id.unqual]") in E is a [*template-id*](temp.names#nt:template-id "13.3Names 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.1General[dcl.decl.general]") corresponds ([[basic.scope.scope]](basic.scope.scope "6.4.1General")) 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.7Deducing 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.1General[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.1General[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.7Reachability")) 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.1General[expr.prim.id.general]") in
the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") of the [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") is
a [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3Qualified names[expr.prim.id.qual]") Q,
let S be its lookup context ([[basic.lookup.qual]](basic.lookup.qual "6.5.5Qualified 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.1General[dcl.decl.general]")[.](#3.2.sentence-1)
- [(3.3)](#3.3)
If the [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") declares
an explicit instantiation or a partial or explicit specialization,
the [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[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.1General[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.7Deducing template arguments from a function declaration"))[.](#3.3.sentence-2)
[*Example [1](#example-1)*: namespace N {inline namespace O {template<class T> void f(T); // #1template<class T> void g(T) {}}namespace P {template<class T> void f(T*); // #2, more specialized than #1template<class> 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.1General[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.1General[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.1General[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.6Functions")) or uses the extern specifier,
the declaration shall not be attached to a named module ([[module.unit]](module.unit "10.1Module 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.3Qualified 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.3Function specifiers[dcl.fct.spec]") applies directly to each [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") in a declaration;
the type specified for each [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") depends on
both the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[dcl.spec.general]") and its [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[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.1General[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.1Attribute syntax and semantics[dcl.attr.grammar]")opt[*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1General[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.1General[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.1General[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.1General[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.3Simple 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.1Attribute syntax and semantics[dcl.attr.grammar]")optTD whereD is an unadorned [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]"),
the type of the declared entity is
“€[.](#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.1General[dcl.decl.general]") is the same as that of the contained[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[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.1General[dcl.decl.general]"),
but they can alter the binding of complex declarators[.](#8.sentence-2)