1521 lines
84 KiB
Markdown
1521 lines
84 KiB
Markdown
[dcl.meaning]
|
||
|
||
# 9 Declarations [[dcl]](./#dcl)
|
||
|
||
## 9.3 Declarators [[dcl.decl]](dcl.decl#dcl.meaning)
|
||
|
||
### 9.3.4 Meaning of declarators [dcl.meaning]
|
||
|
||
#### [9.3.4.1](#general) General [[dcl.meaning.general]](dcl.meaning.general)
|
||
|
||
[1](#general-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[.](#general-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"))[.](#general-1.sentence-2)
|
||
|
||
[*Note [1](#general-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"))[.](#general-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[.](#general-1.sentence-4)
|
||
|
||
[2](#general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L2799)
|
||
|
||
If the declaration is a friend declaration:
|
||
|
||
- [(2.1)](#general-2.1)
|
||
|
||
The [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") does not bind a name[.](#general-2.1.sentence-1)
|
||
|
||
- [(2.2)](#general-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)](#general-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)](#general-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)](#general-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)](#general-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[.](#general-2.2.1.sentence-1)
|
||
|
||
* [(2.2.2)](#general-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[.](#general-2.2.2.sentence-1)
|
||
|
||
- [(2.3)](#general-2.3)
|
||
|
||
Otherwise, the terminal name of E is not looked up[.](#general-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[.](#general-2.3.sentence-2)
|
||
|
||
[3](#general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L2840)
|
||
|
||
Otherwise:
|
||
|
||
- [(3.1)](#general-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[.](#general-3.1.sentence-1)
|
||
|
||
- [(3.2)](#general-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]")[.](#general-3.2.sentence-1)
|
||
|
||
- [(3.3)](#general-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[.](#general-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"))[.](#general-3.3.sentence-2)
|
||
[*Example [1](#general-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)](#general-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[.](#general-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[.](#general-3.4.sentence-2)
|
||
[*Example [2](#general-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)](#general-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[.](#general-3.5.sentence-1)
|
||
[*Example [3](#general-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](#general-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]")[.](#general-4.sentence-1)
|
||
|
||
[5](#general-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[.](#general-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[.](#general-5.sentence-2)
|
||
|
||
[6](#general-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[.](#general-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[.](#general-6.sentence-2)
|
||
|
||
[*Example [4](#general-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"))[.](#general-6.sentence-3)
|
||
|
||
â *end example*]
|
||
|
||
[7](#general-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â[.](#general-7.sentence-1)
|
||
|
||
[8](#general-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[.](#general-8.sentence-2)
|
||
|
||
#### [9.3.4.2](#dcl.ptr) Pointers [[dcl.ptr]](dcl.ptr)
|
||
|
||
[1](#dcl.ptr-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3032)
|
||
|
||
In a declarationTD whereD has the form
|
||
|
||
* [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]")opt D1
|
||
|
||
and the type of the contained [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in the declarationTD1 is â*derived-declarator-type-list*Tâ,
|
||
the type of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") inD is â*derived-declarator-type-list* [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") pointer toTâ[.](#dcl.ptr-1.sentence-1)
|
||
|
||
The[*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1 General [dcl.decl.general]")*s* apply to the pointer and not to the object pointed to[.](#dcl.ptr-1.sentence-2)
|
||
|
||
Similarly, the optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ([[dcl.attr.grammar]](dcl.attr.grammar "9.13.1 Attribute syntax and semantics")) appertains to the pointer and not to the object pointed to[.](#dcl.ptr-1.sentence-3)
|
||
|
||
[2](#dcl.ptr-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3058)
|
||
|
||
[*Example [1](#dcl.ptr-example-1)*:
|
||
|
||
The declarationsconst int ci = 10, *pc = &ci, *const cpc = pc, **ppc;int i, *p, *const cp = &i; declareci,
|
||
a constant integer;pc,
|
||
a pointer to a constant integer;cpc,
|
||
a constant pointer to a constant integer;ppc,
|
||
a pointer to a pointer to a constant integer;i,
|
||
an integer;p,
|
||
a pointer to integer; andcp,
|
||
a constant pointer to integer[.](#dcl.ptr-2.sentence-1)
|
||
|
||
The value ofci,cpc,
|
||
andcp cannot be changed after initialization[.](#dcl.ptr-2.sentence-2)
|
||
|
||
The value ofpc can be changed, and so can the object pointed to bycp[.](#dcl.ptr-2.sentence-3)
|
||
|
||
Examples of
|
||
some correct operations arei = ci;*cp = ci;
|
||
pc++;
|
||
pc = cpc;
|
||
pc = p;
|
||
ppc = &pc;
|
||
|
||
Examples of ill-formed operations areci = 1; // error ci++; // error*pc = 2; // error cp = &ci; // error cpc++; // error p = pc; // error ppc = &p; // error
|
||
|
||
Each is unacceptable because it would either change the value of an object declaredconst or allow it to be changed through a cv-unqualified pointer later, for example:*ppc = &ci; // OK, but would make p point to ci because of previous error*p = 5; // clobber ci
|
||
|
||
â *end example*]
|
||
|
||
[3](#dcl.ptr-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3121)
|
||
|
||
See also [[expr.assign]](expr.assign "7.6.19 Assignment and compound assignment operators") and [[dcl.init]](dcl.init "9.5 Initializers")[.](#dcl.ptr-3.sentence-1)
|
||
|
||
[4](#dcl.ptr-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3124)
|
||
|
||
[*Note [1](#dcl.ptr-note-1)*:
|
||
|
||
Forming a pointer to reference type is ill-formed; see [[dcl.ref]](#dcl.ref "9.3.4.3 References")[.](#dcl.ptr-4.sentence-1)
|
||
|
||
Forming a function pointer type is ill-formed if the function type has[*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1 General [dcl.decl.general]")*s* or a [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]");
|
||
see [[dcl.fct]](#dcl.fct "9.3.4.6 Functions")[.](#dcl.ptr-4.sentence-2)
|
||
|
||
Since the address of a bit-field ([[class.bit]](class.bit "11.4.10 Bit-fields")) cannot be taken,
|
||
a pointer can never point to a bit-field[.](#dcl.ptr-4.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
#### [9.3.4.3](#dcl.ref) References [[dcl.ref]](dcl.ref)
|
||
|
||
[1](#dcl.ref-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3137)
|
||
|
||
In a declarationTD whereD has either of the forms
|
||
|
||
& [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt D1
|
||
&& [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt D1
|
||
|
||
and the type of the contained [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in the declarationTD1 is â*derived-declarator-type-list*Tâ,
|
||
the type of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") inD is â*derived-declarator-type-list* reference toTâ[.](#dcl.ref-1.sentence-1)
|
||
|
||
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") appertains to the reference type[.](#dcl.ref-1.sentence-2)
|
||
|
||
Cv-qualified references are ill-formed except when the cv-qualifiers
|
||
are introduced through the use of 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.param]](temp.param "13.2 Template parameters")) or[*decltype-specifier*](dcl.type.decltype#nt:decltype-specifier "9.2.9.6 Decltype specifiers [dcl.type.decltype]") ([[dcl.type.decltype]](dcl.type.decltype "9.2.9.6 Decltype specifiers")),
|
||
in which case the cv-qualifiers are ignored[.](#dcl.ref-1.sentence-3)
|
||
|
||
[*Example [1](#dcl.ref-example-1)*: typedef int& A;const A aref = 3; // error: lvalue reference to non-const initialized with rvalue
|
||
|
||
The type ofaref is âlvalue reference to intâ,
|
||
not âlvalue reference to const intâ[.](#dcl.ref-1.sentence-4)
|
||
|
||
â *end example*]
|
||
|
||
[*Note [1](#dcl.ref-note-1)*:
|
||
|
||
A reference can be thought of as a name of an object[.](#dcl.ref-1.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
Forming the type
|
||
âreference to cv voidâ
|
||
is ill-formed[.](#dcl.ref-1.sentence-6)
|
||
|
||
[2](#dcl.ref-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3183)
|
||
|
||
A reference type that is declared using & is called an[*lvalue reference*](#def:lvalue_reference "9.3.4.3 References [dcl.ref]"), and a reference type that
|
||
is declared using && is called an[*rvalue reference*](#def:rvalue_reference "9.3.4.3 References [dcl.ref]")[.](#dcl.ref-2.sentence-1)
|
||
|
||
Lvalue references and
|
||
rvalue references are distinct types[.](#dcl.ref-2.sentence-2)
|
||
|
||
Except where explicitly noted, they are
|
||
semantically equivalent and commonly referred to as references[.](#dcl.ref-2.sentence-3)
|
||
|
||
[3](#dcl.ref-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3191)
|
||
|
||
[*Example [2](#dcl.ref-example-2)*:
|
||
|
||
void f(double& a) { a += 3.14; }// ...double d = 0;
|
||
f(d); declaresa to be a reference parameter off so the callf(d) will add3.14 tod[.](#dcl.ref-3.sentence-1)
|
||
|
||
int v[20];// ...int& g(int i) { return v[i]; }// ... g(3) = 7; declares the functiong() to return a reference to an integer sog(3)=7 will assign7 to the fourth element of the arrayv[.](#dcl.ref-3.sentence-2)
|
||
|
||
For another example,struct link { link* next;};
|
||
|
||
link* first;
|
||
|
||
void h(link*& p) { // p is a reference to pointer p->next = first;
|
||
first = p;
|
||
p = 0;}void k() { link* q = new link;
|
||
h(q);} declaresp to be a reference to a pointer tolink soh(q) will leaveq with the value zero[.](#dcl.ref-3.sentence-3)
|
||
|
||
See also [[dcl.init.ref]](dcl.init.ref "9.5.4 References")[.](#dcl.ref-3.sentence-4)
|
||
|
||
â *end example*]
|
||
|
||
[4](#dcl.ref-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3258)
|
||
|
||
It is unspecified whether or not
|
||
a reference requires storage ([[basic.stc]](basic.stc "6.8.6 Storage duration"))[.](#dcl.ref-4.sentence-1)
|
||
|
||
[5](#dcl.ref-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3262)
|
||
|
||
There shall be no references to references,
|
||
no arrays of references, and no pointers to references[.](#dcl.ref-5.sentence-1)
|
||
|
||
The declaration of a reference shall contain an[*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]") ([[dcl.init.ref]](dcl.init.ref "9.5.4 References"))
|
||
except when the declaration contains an explicitextern specifier ([[dcl.stc]](dcl.stc "9.2.2 Storage class specifiers")),
|
||
is a class member ([[class.mem]](class.mem "11.4 Class members")) declaration within a class definition,
|
||
or is the declaration of a parameter or a return type ([[dcl.fct]](#dcl.fct "9.3.4.6 Functions")); see [[basic.def]](basic.def "6.2 Declarations and definitions")[.](#dcl.ref-5.sentence-2)
|
||
|
||
[6](#dcl.ref-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3275)
|
||
|
||
Attempting to bind a reference to a function where
|
||
the converted initializer is a glvalue whose
|
||
type is not call-compatible ([[expr.call]](expr.call "7.6.1.3 Function call"))
|
||
with the type of the function's definition
|
||
results in undefined behavior[.](#dcl.ref-6.sentence-1)
|
||
|
||
Attempting to bind a reference to an object where
|
||
the converted initializer is a glvalue through which
|
||
the object is not type-accessible ([[basic.lval]](basic.lval "7.2.1 Value category"))
|
||
results in undefined behavior[.](#dcl.ref-6.sentence-2)
|
||
|
||
[*Note [2](#dcl.ref-note-2)*:
|
||
|
||
The object designated by such a glvalue can be
|
||
outside its lifetime ([[basic.life]](basic.life "6.8.4 Lifetime"))[.](#dcl.ref-6.sentence-3)
|
||
|
||
Because a null pointer value or a pointer past the end of an object
|
||
does not point to an object,
|
||
a reference in a well-defined program cannot refer to such things;
|
||
see [[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators")[.](#dcl.ref-6.sentence-4)
|
||
|
||
As described in [[class.bit]](class.bit "11.4.10 Bit-fields"), a reference cannot be bound directly
|
||
to a bit-field[.](#dcl.ref-6.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
The behavior of an evaluation of a reference ([[expr.prim.id]](expr.prim.id "7.5.5 Names"), [[expr.ref]](expr.ref "7.6.1.5 Class member access")) that
|
||
does not happen after ([[intro.races]](intro.races "6.10.2.2 Data races")) the initialization of the reference
|
||
is undefined[.](#dcl.ref-6.sentence-6)
|
||
|
||
[*Example [3](#dcl.ref-example-3)*: int &f(int&);int &g();extern int &ir3;int *ip = 0;int &ir1 = *ip; // undefined behavior: null pointerint &ir2 = f(ir3); // undefined behavior: ir3 not yet initializedint &ir3 = g();int &ir4 = f(ir4); // undefined behavior: ir4 used in its own initializerchar x alignas(int);int &ir5 = *reinterpret_cast<int *>(&x); // undefined behavior: initializer refers to char object â *end example*]
|
||
|
||
[7](#dcl.ref-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3315)
|
||
|
||
If 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.param]](temp.param "13.2 Template parameters"))
|
||
or a [*decltype-specifier*](dcl.type.decltype#nt:decltype-specifier "9.2.9.6 Decltype specifiers [dcl.type.decltype]") ([[dcl.type.decltype]](dcl.type.decltype "9.2.9.6 Decltype specifiers")) denotes a type TR that
|
||
is a reference to a type T, an attempt to create the type âlvalue reference to cv TRâ
|
||
creates the type âlvalue reference to Tâ, while an attempt to create
|
||
the type ârvalue reference to cv TRâ creates the type TR[.](#dcl.ref-7.sentence-1)
|
||
|
||
[*Note [3](#dcl.ref-note-3)*:
|
||
|
||
This rule is known as reference collapsing[.](#dcl.ref-7.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [4](#dcl.ref-example-4)*: int i;typedef int& LRI;typedef int&& RRI;
|
||
|
||
LRI& r1 = i; // r1 has the type int&const LRI& r2 = i; // r2 has the type int&const LRI&& r3 = i; // r3 has the type int& RRI& r4 = i; // r4 has the type int& RRI&& r5 = 5; // r5 has the type int&&decltype(r2)& r6 = i; // r6 has the type int&decltype(r2)&& r7 = i; // r7 has the type int& â *end example*]
|
||
|
||
[8](#dcl.ref-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3343)
|
||
|
||
[*Note [4](#dcl.ref-note-4)*:
|
||
|
||
Forming a reference to function type is ill-formed if the function
|
||
type has [*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1 General [dcl.decl.general]")*s* or a [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]");
|
||
see [[dcl.fct]](#dcl.fct "9.3.4.6 Functions")[.](#dcl.ref-8.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
#### [9.3.4.4](#dcl.mptr) Pointers to members [[dcl.mptr]](dcl.mptr)
|
||
|
||
[1](#dcl.mptr-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3354)
|
||
|
||
The component names of a [*ptr-operator*](dcl.decl.general#nt:ptr-operator "9.3.1 General [dcl.decl.general]") are
|
||
those of its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"), if any[.](#dcl.mptr-1.sentence-1)
|
||
|
||
[2](#dcl.mptr-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3359)
|
||
|
||
In a declarationTD whereD has the form
|
||
|
||
[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") * [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]")opt D1
|
||
|
||
and the[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") designates a class,
|
||
and the type of the contained [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in the declarationTD1 is â*derived-declarator-type-list*Tâ,
|
||
the type of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") inD is â*derived-declarator-type-list* [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") pointer to member of class[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") of typeTâ[.](#dcl.mptr-2.sentence-1)
|
||
|
||
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ([[dcl.attr.grammar]](dcl.attr.grammar "9.13.1 Attribute syntax and semantics")) appertains to the
|
||
pointer-to-member[.](#dcl.mptr-2.sentence-2)
|
||
|
||
The [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") shall not designate an anonymous union[.](#dcl.mptr-2.sentence-3)
|
||
|
||
[3](#dcl.mptr-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3386)
|
||
|
||
[*Example [1](#dcl.mptr-example-1)*:
|
||
|
||
struct X {void f(int); int a;};struct Y;
|
||
|
||
int X::* pmi = &X::a;void (X::* pmf)(int) = &X::f;double X::* pmd;char Y::* pmc; declarespmi,pmf,pmd andpmc to be a pointer to a member ofX of typeint,
|
||
a pointer to a member ofX of typevoid(int),
|
||
a pointer to a member ofX of typedouble and a pointer to a member ofY of typechar respectively[.](#dcl.mptr-3.sentence-1)
|
||
|
||
The declaration ofpmd is well-formed even thoughX has no members of typedouble[.](#dcl.mptr-3.sentence-2)
|
||
|
||
Similarly, the declaration ofpmc is well-formed even thoughY is an incomplete type[.](#dcl.mptr-3.sentence-3)
|
||
|
||
pmi andpmf can be used like this:X obj;// ... obj.*pmi = 7; // assign 7 to an integer member of obj(obj.*pmf)(7); // call a function member of obj with the argument 7
|
||
|
||
â *end example*]
|
||
|
||
[4](#dcl.mptr-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3446)
|
||
|
||
A pointer to member shall not point to a static member
|
||
of a class ([[class.static]](class.static "11.4.9 Static members")),
|
||
a member with reference type,
|
||
or
|
||
âcv voidâ[.](#dcl.mptr-4.sentence-1)
|
||
|
||
[5](#dcl.mptr-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3453)
|
||
|
||
[*Note [1](#dcl.mptr-note-1)*:
|
||
|
||
See also [[expr.unary]](expr.unary "7.6.2 Unary expressions") and [[expr.mptr.oper]](expr.mptr.oper "7.6.4 Pointer-to-member operators")[.](#dcl.mptr-5.sentence-1)
|
||
|
||
The type âpointer to memberâ is distinct from the type âpointerâ,
|
||
that is, a pointer to member is declared only by the pointer-to-member
|
||
declarator syntax, and never by the pointer declarator syntax[.](#dcl.mptr-5.sentence-2)
|
||
|
||
There is no âreference-to-memberâ type in C++[.](#dcl.mptr-5.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
#### [9.3.4.5](#dcl.array) Arrays [[dcl.array]](dcl.array)
|
||
|
||
[1](#dcl.array-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3465)
|
||
|
||
In a declaration T D where D has the form
|
||
|
||
D1 [ [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]")opt ] [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt
|
||
|
||
and the type of the contained [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in the declaration T D1 is â*derived-declarator-type-list* Tâ,
|
||
the type of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in D is
|
||
â*derived-declarator-type-list* array of N Tâ[.](#dcl.array-1.sentence-1)
|
||
|
||
The [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") shall be a converted constant expression of type std::size_t ([[expr.const]](expr.const "7.7 Constant expressions"))[.](#dcl.array-1.sentence-2)
|
||
|
||
Its value N specifies the [*array bound*](#def:array,bound "9.3.4.5 Arrays [dcl.array]"),
|
||
i.e., the number of elements in the array;N shall be greater than zero[.](#dcl.array-1.sentence-3)
|
||
|
||
[2](#dcl.array-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3482)
|
||
|
||
In a declaration T D where D has the form
|
||
|
||
D1 [ ] [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt
|
||
|
||
and the type of the contained [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in the declaration T D1 is â*derived-declarator-type-list* Tâ,
|
||
the type of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in D is
|
||
â*derived-declarator-type-list* array of unknown bound of Tâ, except as specified below[.](#dcl.array-2.sentence-1)
|
||
|
||
[3](#dcl.array-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3493)
|
||
|
||
A type of the form âarray of N Uâ or
|
||
âarray of unknown bound of Uâ is an [*array type*](#def:array_type "9.3.4.5 Arrays [dcl.array]")[.](#dcl.array-3.sentence-1)
|
||
|
||
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") appertains to the array type[.](#dcl.array-3.sentence-2)
|
||
|
||
[4](#dcl.array-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3501)
|
||
|
||
U is called the array [*element type*](#def:element_type "9.3.4.5 Arrays [dcl.array]");
|
||
this type shall not be
|
||
a reference type,
|
||
a function type,
|
||
an array of unknown bound, orcv void[.](#dcl.array-4.sentence-1)
|
||
|
||
[*Note [1](#dcl.array-note-1)*:
|
||
|
||
An array can be constructed
|
||
from one of the fundamental types (except void),
|
||
from a pointer,
|
||
from a pointer to member,
|
||
from a class,
|
||
from an enumeration type,
|
||
or from an array of known bound[.](#dcl.array-4.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [1](#dcl.array-example-1)*:
|
||
|
||
float fa[17], *afp[17]; declares an array of float numbers and
|
||
an array of pointers to float numbers[.](#dcl.array-4.sentence-3)
|
||
|
||
â *end example*]
|
||
|
||
[5](#dcl.array-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3525)
|
||
|
||
Any type of the form
|
||
â[*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") array of N Uâ
|
||
is adjusted to
|
||
âarray of N [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") Uâ,
|
||
and similarly for âarray of unknown bound of Uâ[.](#dcl.array-5.sentence-1)
|
||
|
||
[*Example [2](#dcl.array-example-2)*: typedef int A[5], AA[2][3];typedef const A CA; // type is âarray of 5 const int''typedef const AA CAA; // type is âarray of 2 array of 3 const int'' â *end example*]
|
||
|
||
[*Note [2](#dcl.array-note-2)*:
|
||
|
||
An âarray of N [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") Uâ
|
||
has cv-qualified type; see [[basic.type.qualifier]](basic.type.qualifier "6.9.5 CV-qualifiers")[.](#dcl.array-5.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[6](#dcl.array-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3543)
|
||
|
||
An object of type âarray of N Uâ consists of
|
||
a contiguously allocated non-empty set
|
||
of N subobjects of type U,
|
||
known as the [*elements*](#def:array,element "9.3.4.5 Arrays [dcl.array]") of the array,
|
||
and numbered 0 to N-1[.](#dcl.array-6.sentence-1)
|
||
|
||
[7](#dcl.array-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3550)
|
||
|
||
In addition to declarations in which an incomplete object type is allowed,
|
||
an array bound may be omitted in some cases in the declaration of a function
|
||
parameter ([[dcl.fct]](#dcl.fct "9.3.4.6 Functions"))[.](#dcl.array-7.sentence-1)
|
||
|
||
An array bound may also be omitted
|
||
when an object (but not a non-static data member) of array type is initialized
|
||
and the declarator is followed by
|
||
an initializer ([[dcl.init]](dcl.init "9.5 Initializers"), [[class.mem]](class.mem "11.4 Class members"), [[expr.type.conv]](expr.type.conv "7.6.1.4 Explicit type conversion (functional notation)"), [[expr.new]](expr.new "7.6.2.8 New"))[.](#dcl.array-7.sentence-2)
|
||
|
||
In these cases, the array bound is calculated
|
||
from the number of initial elements (say, N)
|
||
supplied ([[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates")),
|
||
and the type of the array is âarray of N Uâ[.](#dcl.array-7.sentence-3)
|
||
|
||
[8](#dcl.array-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3564)
|
||
|
||
Furthermore, if there is a reachable declaration of the entity
|
||
that specifies a bound and
|
||
has the same host scope ([[basic.scope.scope]](basic.scope.scope "6.4.1 General")),
|
||
an omitted array bound is taken to
|
||
be the same as in that earlier declaration, and similarly for the definition
|
||
of a static data member of a class[.](#dcl.array-8.sentence-1)
|
||
|
||
[*Example [3](#dcl.array-example-3)*: extern int x[10];struct S {static int y[10];};
|
||
|
||
int x[]; // OK, bound is 10int S::y[]; // OK, bound is 10void f() {extern int x[]; int i = sizeof(x); // error: incomplete object type}namespace A { extern int z[3]; }int A::z[] = {}; // OK, defines an array of 3 elements â *end example*]
|
||
|
||
[9](#dcl.array-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3591)
|
||
|
||
[*Note [3](#dcl.array-note-3)*:
|
||
|
||
When several âarray ofâ specifications are adjacent,
|
||
a multidimensional array type is created;
|
||
only the first of the constant expressions
|
||
that specify the bounds of the arrays can be omitted[.](#dcl.array-9.sentence-1)
|
||
|
||
[*Example [4](#dcl.array-example-4)*:
|
||
|
||
int x3d[3][5][7]; declares an array of three elements,
|
||
each of which is an array of five elements,
|
||
each of which is an array of seven integers[.](#dcl.array-9.sentence-2)
|
||
|
||
The overall array can be viewed as a
|
||
three-dimensional array of integers,
|
||
with rank 3 ×5 ×7[.](#dcl.array-9.sentence-3)
|
||
|
||
Any of the expressionsx3d,x3d[i],x3d[i][j],x3d[i][j][k] can reasonably appear in an expression[.](#dcl.array-9.sentence-4)
|
||
|
||
The expressionx3d[i] is equivalent to*(x3d + i);
|
||
in that expression,x3d is subject to the array-to-pointer conversion ([[conv.array]](conv.array "7.3.3 Array-to-pointer conversion"))
|
||
and is first converted to
|
||
a pointer to a 2-dimensional
|
||
array with rank5 ×7 that points to the first element of x3d[.](#dcl.array-9.sentence-5)
|
||
|
||
Then i is added,
|
||
which on typical implementations involves multiplyingi by the
|
||
length of the object to which the pointer points,
|
||
which is sizeof(int)×5 ×7[.](#dcl.array-9.sentence-6)
|
||
|
||
The result of the addition and indirection is
|
||
an lvalue denoting
|
||
the ith array element ofx3d (an array of five arrays of seven integers)[.](#dcl.array-9.sentence-7)
|
||
|
||
If there is another subscript,
|
||
the same argument applies again, sox3d[i][j] is
|
||
an lvalue denoting
|
||
the jth array element of
|
||
the ith array element ofx3d (an array of seven integers), andx3d[i][j][k] is
|
||
an lvalue denoting
|
||
the kth array element of
|
||
the jth array element of
|
||
the ith array element ofx3d (an integer)[.](#dcl.array-9.sentence-8)
|
||
|
||
â *end example*]
|
||
|
||
The first subscript in the declaration helps determine
|
||
the amount of storage consumed by an array
|
||
but plays no other part in subscript calculations[.](#dcl.array-9.sentence-9)
|
||
|
||
â *end note*]
|
||
|
||
[10](#dcl.array-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3657)
|
||
|
||
[*Note [4](#dcl.array-note-4)*:
|
||
|
||
Conversions affecting expressions of array type are described in [[conv.array]](conv.array "7.3.3 Array-to-pointer conversion")[.](#dcl.array-10.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[11](#dcl.array-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3662)
|
||
|
||
[*Note [5](#dcl.array-note-5)*:
|
||
|
||
The subscript operator can be overloaded for a class ([[over.sub]](over.sub "12.4.5 Subscripting"))[.](#dcl.array-11.sentence-1)
|
||
|
||
For the operator's built-in meaning, see [[expr.sub]](expr.sub "7.6.1.2 Subscripting")[.](#dcl.array-11.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
#### [9.3.4.6](#dcl.fct) Functions [[dcl.fct]](dcl.fct)
|
||
|
||
[1](#dcl.fct-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3671)
|
||
|
||
In a declarationTD whereT may be empty andD has the form
|
||
|
||
D1 ( [*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") ) [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]")opt
|
||
[*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]")opt [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]")opt [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]")opt
|
||
|
||
a *derived-declarator-type-list* is determined as follows:
|
||
|
||
- [(1.1)](#dcl.fct-1.1)
|
||
|
||
If the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") of the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") is a [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]"),
|
||
the *derived-declarator-type-list* is empty[.](#dcl.fct-1.1.sentence-1)
|
||
|
||
- [(1.2)](#dcl.fct-1.2)
|
||
|
||
Otherwise, the *derived-declarator-type-list* is as appears in
|
||
the type â*derived-declarator-type-list* Tâ
|
||
of the contained[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") in the declarationTD1[.](#dcl.fct-1.2.sentence-1)
|
||
|
||
The declared return type U of the function type
|
||
is determined as follows:
|
||
|
||
- [(1.3)](#dcl.fct-1.3)
|
||
|
||
If the [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]") is present,T shall be the single [*type-specifier*](dcl.type.general#nt:type-specifier "9.2.9.1 General [dcl.type.general]") auto, andU is the type specified by the [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]")[.](#dcl.fct-1.3.sentence-1)
|
||
|
||
- [(1.4)](#dcl.fct-1.4)
|
||
|
||
Otherwise, if the declaration declares a conversion function,
|
||
see [[class.conv.fct]](class.conv.fct "11.4.8.3 Conversion functions")[.](#dcl.fct-1.4.sentence-1)
|
||
|
||
- [(1.5)](#dcl.fct-1.5)
|
||
|
||
Otherwise, U is T[.](#dcl.fct-1.5.sentence-1)
|
||
|
||
The type of the[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") inD is
|
||
â*derived-declarator-type-list*noexceptopt function of parameter-type-list[*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]")opt [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]")opt returning Uâ, where
|
||
|
||
- [(1.6)](#dcl.fct-1.6)
|
||
|
||
the parameter-type-list is derived from
|
||
the [*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") as described below and
|
||
|
||
- [(1.7)](#dcl.fct-1.7)
|
||
|
||
the optional noexcept is present if and only if
|
||
the exception specification ([[except.spec]](except.spec "14.5 Exception specifications")) is non-throwing[.](#dcl.fct-1.sentence-3)
|
||
|
||
Such a type is a [*function type*](#def:type,function "9.3.4.6 Functions [dcl.fct]")[.](#dcl.fct-1.sentence-4)[75](#footnote-75 "As indicated by syntax, cv-qualifiers are a significant component in function return types.")
|
||
|
||
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") appertains to the function type[.](#dcl.fct-1.sentence-5)
|
||
|
||
[2](#dcl.fct-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3740)
|
||
|
||
[parameter-declaration-clause:](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]")
|
||
...
|
||
[*parameter-declaration-list*](#nt:parameter-declaration-list "9.3.4.6 Functions [dcl.fct]")opt
|
||
[*parameter-declaration-list*](#nt:parameter-declaration-list "9.3.4.6 Functions [dcl.fct]") , ...
|
||
[*parameter-declaration-list*](#nt:parameter-declaration-list "9.3.4.6 Functions [dcl.fct]") ...
|
||
|
||
[parameter-declaration-list:](#nt:parameter-declaration-list "9.3.4.6 Functions [dcl.fct]")
|
||
[*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]")
|
||
[*parameter-declaration-list*](#nt:parameter-declaration-list "9.3.4.6 Functions [dcl.fct]") , [*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]")
|
||
|
||
[parameter-declaration:](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]")
|
||
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt thisopt [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]") [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]")
|
||
[*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]") [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") = [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]")
|
||
[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt thisopt [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]") [*abstract-declarator*](dcl.name#nt:abstract-declarator "9.3.2 Type names [dcl.name]")opt
|
||
[*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]") [*abstract-declarator*](dcl.name#nt:abstract-declarator "9.3.2 Type names [dcl.name]")opt = [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]")
|
||
|
||
The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") in a [*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") appertains to the parameter[.](#dcl.fct-2.sentence-1)
|
||
|
||
[3](#dcl.fct-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3767)
|
||
|
||
The[*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") determines the arguments that can be specified, and their processing, when the function is called[.](#dcl.fct-3.sentence-1)
|
||
|
||
[*Note [1](#dcl.fct-note-1)*:
|
||
|
||
The[*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") is used to convert the arguments specified on the function call;
|
||
see [[expr.call]](expr.call "7.6.1.3 Function call")[.](#dcl.fct-3.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
If the[*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") is empty, the function takes no arguments[.](#dcl.fct-3.sentence-3)
|
||
|
||
A parameter list consisting of a single unnamed non-object parameter of
|
||
non-dependent type void is equivalent to an empty parameter
|
||
list[.](#dcl.fct-3.sentence-4)
|
||
|
||
Except for this special case, a parameter shall not have type cv void[.](#dcl.fct-3.sentence-5)
|
||
|
||
A parameter with volatile-qualified type is deprecated;
|
||
see [[depr.volatile.type]](depr.volatile.type "D.4 Deprecated volatile types")[.](#dcl.fct-3.sentence-6)
|
||
|
||
If the[*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]")terminates with an ellipsis or a function parameter
|
||
pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates")), the number of arguments shall be equal
|
||
to or greater than the number of parameters that do not have a default
|
||
argument and are not function parameter packs[.](#dcl.fct-3.sentence-7)
|
||
|
||
Where syntactically correct and where â...â is not
|
||
part of an [*abstract-declarator*](dcl.name#nt:abstract-declarator "9.3.2 Type names [dcl.name]"),
|
||
â...â
|
||
is synonymous with
|
||
â, ...â[.](#dcl.fct-3.sentence-8)
|
||
|
||
A [*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") of the form[*parameter-declaration-list*](#nt:parameter-declaration-list "9.3.4.6 Functions [dcl.fct]") ... is deprecated ([[depr.ellipsis.comma]](depr.ellipsis.comma "D.5 Non-comma-separated ellipsis parameters"))[.](#dcl.fct-3.sentence-9)
|
||
|
||
[*Example [1](#dcl.fct-example-1)*:
|
||
|
||
The declarationint printf(const char*, ...); declares a function that can be called with varying numbers and types of arguments[.](#dcl.fct-3.sentence-10)
|
||
|
||
printf("hello world");
|
||
printf("a=%d b=%d", a, b);
|
||
|
||
However, the first argument must be of a type
|
||
that can be converted to aconstchar*[.](#dcl.fct-3.sentence-11)
|
||
|
||
â *end example*]
|
||
|
||
[*Note [2](#dcl.fct-note-2)*:
|
||
|
||
The standard header [<cstdarg>](cstdarg.syn#header:%3ccstdarg%3e "17.14.2 Header <cstdarg> synopsis [cstdarg.syn]") contains a mechanism for accessing arguments passed using the ellipsis
|
||
(see [[expr.call]](expr.call "7.6.1.3 Function call") and [[support.runtime]](support.runtime "17.14 Other runtime support"))[.](#dcl.fct-3.sentence-12)
|
||
|
||
â *end note*]
|
||
|
||
[4](#dcl.fct-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3833)
|
||
|
||
The type of a function is determined using the following rules[.](#dcl.fct-4.sentence-1)
|
||
|
||
The type of each parameter (including function parameter packs) is
|
||
determined from its own [*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") ([[dcl.decl]](dcl.decl "9.3 Declarators"))[.](#dcl.fct-4.sentence-2)
|
||
|
||
After determining the type of each parameter, any parameterof type âarray of Tâ orof function type T is adjusted to be âpointer to Tâ[.](#dcl.fct-4.sentence-3)
|
||
|
||
After producing the list of parameter types,
|
||
any top-level[*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1 General [dcl.decl.general]")*s* modifying a parameter type are deleted
|
||
when forming the function type[.](#dcl.fct-4.sentence-4)
|
||
|
||
The resulting list of transformed parameter types
|
||
and the presence or absence of the ellipsis or a function parameter pack
|
||
is the function's[*parameter-type-list*](#def:parameter-type-list "9.3.4.6 Functions [dcl.fct]")[.](#dcl.fct-4.sentence-5)
|
||
|
||
[*Note [3](#dcl.fct-note-3)*:
|
||
|
||
This transformation does not affect the types of the parameters[.](#dcl.fct-4.sentence-6)
|
||
|
||
For example, int(*)(const int p, decltype(p)*) andint(*)(int, const int*) are identical types[.](#dcl.fct-4.sentence-7)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [2](#dcl.fct-example-2)*: void f(char*); // #1void f(char[]) {} // defines #1void f(const char*) {} // OK, another overloadvoid f(char *const) {} // error: redefines #1void g(char(*)[2]); // #2void g(char[3][2]) {} // defines #2void g(char[3][3]) {} // OK, another overloadvoid h(int x(const int)); // #3void h(int (*)(int)) {} // defines #3 â *end example*]
|
||
|
||
[5](#dcl.fct-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3874)
|
||
|
||
An [*explicit-object-parameter-declaration*](#def:explicit-object-parameter-declaration "9.3.4.6 Functions [dcl.fct]") is
|
||
a [*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") with a this specifier[.](#dcl.fct-5.sentence-1)
|
||
|
||
An explicit-object-parameter-declaration shall appear only as
|
||
the first [*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") of
|
||
a [*parameter-declaration-list*](#nt:parameter-declaration-list "9.3.4.6 Functions [dcl.fct]") of one of:
|
||
|
||
- [(5.1)](#dcl.fct-5.1)
|
||
|
||
a declaration of
|
||
a member function or member function template ([[class.mem]](class.mem "11.4 Class members")), or
|
||
|
||
- [(5.2)](#dcl.fct-5.2)
|
||
|
||
an explicit instantiation ([[temp.explicit]](temp.explicit "13.9.3 Explicit instantiation")) or
|
||
explicit specialization ([[temp.expl.spec]](temp.expl.spec "13.9.4 Explicit specialization")) of
|
||
a templated member function, or
|
||
|
||
- [(5.3)](#dcl.fct-5.3)
|
||
|
||
a [*lambda-declarator*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") ([[expr.prim.lambda]](expr.prim.lambda "7.5.6 Lambda expressions"))[.](#dcl.fct-5.sentence-2)
|
||
|
||
A [*member-declarator*](class.mem.general#nt:member-declarator "11.4.1 General [class.mem.general]") with an explicit-object-parameter-declaration
|
||
shall not include
|
||
a [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]") or a [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") and
|
||
shall not be declared static or virtual[.](#dcl.fct-5.sentence-3)
|
||
|
||
[*Example [3](#dcl.fct-example-3)*: struct C {void f(this C& self); template <typename Self> void g(this Self&& self, int); void h(this C) const; // error: const not allowed here};
|
||
|
||
void test(C c) { c.f(); // OK, calls C::f c.g(42); // OK, calls C::g<C&> std::move(c).g(42); // OK, calls C::g<C>} â *end example*]
|
||
|
||
[6](#dcl.fct-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3912)
|
||
|
||
A function parameter declared with an explicit-object-parameter-declaration
|
||
is an [*explicit object parameter*](#def:parameter,explicit_object "9.3.4.6 Functions [dcl.fct]")[.](#dcl.fct-6.sentence-1)
|
||
|
||
An explicit object parameter shall not be
|
||
a function parameter pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#dcl.fct-6.sentence-2)
|
||
|
||
An [*explicit object member function*](#def:member_function,explicit_object "9.3.4.6 Functions [dcl.fct]") is a non-static member function
|
||
with an explicit object parameter[.](#dcl.fct-6.sentence-3)
|
||
|
||
An [*implicit object member function*](#def:member_function,implicit_object "9.3.4.6 Functions [dcl.fct]") is a non-static member function
|
||
without an explicit object parameter[.](#dcl.fct-6.sentence-4)
|
||
|
||
[7](#dcl.fct-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3922)
|
||
|
||
The [*object parameter*](#def:parameter,object "9.3.4.6 Functions [dcl.fct]") of a non-static member function is either
|
||
the explicit object parameter or
|
||
the implicit object parameter ([[over.match.funcs]](over.match.funcs "12.2.2 Candidate functions and argument lists"))[.](#dcl.fct-7.sentence-1)
|
||
|
||
[8](#dcl.fct-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3927)
|
||
|
||
A [*non-object parameter*](#def:parameter,non-object "9.3.4.6 Functions [dcl.fct]") is a function parameter
|
||
that is not the explicit object parameter[.](#dcl.fct-8.sentence-1)
|
||
|
||
The [*non-object-parameter-type-list*](#def:non-object-parameter-type-list "9.3.4.6 Functions [dcl.fct]") of a member function is
|
||
the parameter-type-list of that function with the explicit object parameter,
|
||
if any, omitted[.](#dcl.fct-8.sentence-2)
|
||
|
||
[*Note [4](#dcl.fct-note-4)*:
|
||
|
||
The non-object-parameter-type-list consists of
|
||
the adjusted types of all the non-object parameters[.](#dcl.fct-8.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[9](#dcl.fct-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3938)
|
||
|
||
A function type with a [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") or a[*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]") (including a type denoted by[*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.param]](temp.param "13.2 Template parameters")))
|
||
shall appear only as:
|
||
|
||
- [(9.1)](#dcl.fct-9.1)
|
||
|
||
the function type for a non-static member function,
|
||
|
||
- [(9.2)](#dcl.fct-9.2)
|
||
|
||
the function type to which a pointer to member refers,
|
||
|
||
- [(9.3)](#dcl.fct-9.3)
|
||
|
||
the top-level function type of a function typedef declaration
|
||
or [*alias-declaration*](dcl.pre#nt:alias-declaration "9.1 Preamble [dcl.pre]"),
|
||
|
||
- [(9.4)](#dcl.fct-9.4)
|
||
|
||
the [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") in the default argument of a[*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]") ([[temp.param]](temp.param "13.2 Template parameters")),
|
||
|
||
- [(9.5)](#dcl.fct-9.5)
|
||
|
||
the [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") of a [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") for a[*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]") ([[temp.arg.type]](temp.arg.type "13.4.2 Type template arguments")), or
|
||
|
||
- [(9.6)](#dcl.fct-9.6)
|
||
|
||
the operand of a [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") ([[expr.reflect]](expr.reflect "7.6.2.10 The reflection operator"))[.](#dcl.fct-9.sentence-1)
|
||
|
||
[*Example [4](#dcl.fct-example-4)*: typedef int FIC(int) const;
|
||
FIC f; // error: does not declare a member functionstruct S { FIC f; // OK};
|
||
FIC S::*pm = &S::f; // OKconstexpr std::meta::info yeti = ^^void(int) const &; // OK â *end example*]
|
||
|
||
[10](#dcl.fct-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3971)
|
||
|
||
The effect of a[*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") in a function declarator is not the same as
|
||
adding cv-qualification on top of the function type[.](#dcl.fct-10.sentence-1)
|
||
|
||
In the latter case, the cv-qualifiers are ignored[.](#dcl.fct-10.sentence-2)
|
||
|
||
[*Note [5](#dcl.fct-note-5)*:
|
||
|
||
A function type that has a [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") is not a
|
||
cv-qualified type; there are no cv-qualified function types[.](#dcl.fct-10.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [5](#dcl.fct-example-5)*: typedef void F();struct S {const F f; // OK, equivalent to: void f();}; â *end example*]
|
||
|
||
[11](#dcl.fct-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L3990)
|
||
|
||
The return type, the parameter-type-list, the [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]"),
|
||
the [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]"), and
|
||
the exception specification,
|
||
but not the default arguments ([[dcl.fct.default]](#dcl.fct.default "9.3.4.7 Default arguments"))
|
||
or the trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") ([[dcl.decl]](dcl.decl "9.3 Declarators")),
|
||
are part of the function type[.](#dcl.fct-11.sentence-1)
|
||
|
||
[*Note [6](#dcl.fct-note-6)*:
|
||
|
||
Function types are checked during the assignments and initializations of
|
||
pointers to functions, references to functions, and pointers to member functions[.](#dcl.fct-11.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[12](#dcl.fct-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4002)
|
||
|
||
[*Example [6](#dcl.fct-example-6)*:
|
||
|
||
The declarationint fseek(FILE*, long, int); declares a function taking three arguments of the specified types,
|
||
and returningint ([[dcl.type]](dcl.type "9.2.9 Type specifiers"))[.](#dcl.fct-12.sentence-1)
|
||
|
||
â *end example*]
|
||
|
||
[13](#dcl.fct-13)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4013)
|
||
|
||
[*Note [7](#dcl.fct-note-7)*:
|
||
|
||
A single name can be used for several different functions in a single scope;
|
||
this is function overloading ([[over]](over "12 Overloading"))[.](#dcl.fct-13.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[14](#dcl.fct-14)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4020)
|
||
|
||
The return type shall be a non-array object type, a reference type, or cv void[.](#dcl.fct-14.sentence-1)
|
||
|
||
[*Note [8](#dcl.fct-note-8)*:
|
||
|
||
An array of placeholder type is considered an array type[.](#dcl.fct-14.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[15](#dcl.fct-15)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4028)
|
||
|
||
A volatile-qualified return type is deprecated;
|
||
see [[depr.volatile.type]](depr.volatile.type "D.4 Deprecated volatile types")[.](#dcl.fct-15.sentence-1)
|
||
|
||
[16](#dcl.fct-16)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4032)
|
||
|
||
Types shall not be defined in return or parameter types[.](#dcl.fct-16.sentence-1)
|
||
|
||
[17](#dcl.fct-17)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4035)
|
||
|
||
A typedef of function type may be used to declare a function but shall not be
|
||
used to define a function ([[dcl.fct.def]](dcl.fct.def "9.6 Function definitions"))[.](#dcl.fct-17.sentence-1)
|
||
|
||
[*Example [7](#dcl.fct-example-7)*: typedef void F();
|
||
F fv; // OK, equivalent to void fv(); F fv { } // errorvoid fv() { } // OK, definition of fv â *end example*]
|
||
|
||
[18](#dcl.fct-18)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4048)
|
||
|
||
An identifier can optionally be provided as a parameter name;
|
||
if present in a function definition ([[dcl.fct.def]](dcl.fct.def "9.6 Function definitions")), it names a parameter[.](#dcl.fct-18.sentence-1)
|
||
|
||
[*Note [9](#dcl.fct-note-9)*:
|
||
|
||
In particular, parameter names are also optional in function definitions
|
||
and names used for a parameter in different declarations and the definition
|
||
of a function need not be the same[.](#dcl.fct-18.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[19](#dcl.fct-19)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4057)
|
||
|
||
[*Example [8](#dcl.fct-example-8)*:
|
||
|
||
The declarationint i, *pi,
|
||
f(), *fpi(int), (*pif)(const char*, const char*), (*fpif(int))(int); declares an integeri,
|
||
a pointerpi to an integer,
|
||
a functionf taking no arguments and returning an integer,
|
||
a functionfpi taking an integer argument and returning a pointer to an integer,
|
||
a pointerpif to a function which
|
||
takes two pointers to constant characters and returns an integer,
|
||
a functionfpif taking an integer argument and returning a pointer to a function that takes an integer argument and returns an integer[.](#dcl.fct-19.sentence-1)
|
||
|
||
It is especially useful to comparefpi andpif[.](#dcl.fct-19.sentence-2)
|
||
|
||
The binding of*fpi(int) is*(fpi(int)),
|
||
so the declaration suggests,
|
||
and the same construction in an expression
|
||
requires, the calling of a functionfpi,
|
||
and then using indirection through the (pointer) result
|
||
to yield an integer[.](#dcl.fct-19.sentence-3)
|
||
|
||
In the declarator(*pif)(const char*, const char*),
|
||
the extra parentheses are necessary to indicate that indirection through
|
||
a pointer to a function yields a function, which is then called[.](#dcl.fct-19.sentence-4)
|
||
|
||
â *end example*]
|
||
|
||
[*Note [10](#dcl.fct-note-10)*:
|
||
|
||
Typedefs and [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]")*s* are sometimes convenient when the return type of a function is complex[.](#dcl.fct-19.sentence-5)
|
||
|
||
For example,
|
||
the functionfpif above can be declaredtypedef int IFUNC(int);
|
||
IFUNC* fpif(int); orauto fpif(int)->int(*)(int);
|
||
|
||
A [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]") is most useful for a type that would be more complicated to specify before the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]"):template <class T, class U> auto add(T t, U u) -> decltype(t + u); rather thantemplate <class T, class U> decltype((*(T*)0) + (*(U*)0)) add(T t, U u);
|
||
|
||
â *end note*]
|
||
|
||
[20](#dcl.fct-20)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4130)
|
||
|
||
A [*non-template function*](#def:function,non-template "9.3.4.6 Functions [dcl.fct]") is a function that is not a function template
|
||
specialization[.](#dcl.fct-20.sentence-1)
|
||
|
||
[*Note [11](#dcl.fct-note-11)*:
|
||
|
||
A function template is not a function[.](#dcl.fct-20.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[21](#dcl.fct-21)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4137)
|
||
|
||
An [*abbreviated function template*](#def:template,function,abbreviated "9.3.4.6 Functions [dcl.fct]") is a function declaration that has
|
||
one or more generic parameter type placeholders ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7 Placeholder type specifiers"))[.](#dcl.fct-21.sentence-1)
|
||
|
||
An abbreviated function template is equivalent to
|
||
a function template ([[temp.fct]](temp.fct "13.7.7 Function templates"))
|
||
whose [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") includes
|
||
one invented [*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]") for each generic parameter type placeholder
|
||
of the function declaration, in order of appearance[.](#dcl.fct-21.sentence-2)
|
||
|
||
For a [*placeholder-type-specifier*](dcl.spec.auto.general#nt:placeholder-type-specifier "9.2.9.7.1 General [dcl.spec.auto.general]") of the form auto,
|
||
the invented parameter is
|
||
an unconstrained [*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]")[.](#dcl.fct-21.sentence-3)
|
||
|
||
For a [*placeholder-type-specifier*](dcl.spec.auto.general#nt:placeholder-type-specifier "9.2.9.7.1 General [dcl.spec.auto.general]") of the form[*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]") auto,
|
||
the invented parameter is a [*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]") with
|
||
that [*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]")[.](#dcl.fct-21.sentence-4)
|
||
|
||
The invented [*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]") declares
|
||
a template parameter pack
|
||
if the corresponding [*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") declares a function parameter pack[.](#dcl.fct-21.sentence-5)
|
||
|
||
If the placeholder contains decltype(auto),
|
||
the program is ill-formed[.](#dcl.fct-21.sentence-6)
|
||
|
||
The adjusted function parameters of an abbreviated function template
|
||
are derived from the [*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") by
|
||
replacing each occurrence of a placeholder with
|
||
the name of the corresponding invented [*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]")[.](#dcl.fct-21.sentence-7)
|
||
|
||
[*Example [9](#dcl.fct-example-9)*: template<typename T> concept C1 = /* ... */;template<typename T> concept C2 = /* ... */;template<typename... Ts> concept C3 = /* ... */;
|
||
|
||
void g1(const C1 auto*, C2 auto&);void g2(C1 auto&...);void g3(C3 auto...);void g4(C3 auto);
|
||
|
||
The declarations above are functionally equivalent (but not equivalent) to
|
||
their respective declarations below:template<C1 T, C2 U> void g1(const T*, U&);template<C1... Ts> void g2(Ts&...);template<C3... Ts> void g3(Ts...);template<C3 T> void g4(T);
|
||
|
||
Abbreviated function templates can be specialized like all function templates[.](#dcl.fct-21.sentence-9)
|
||
|
||
template<> void g1<int>(const int*, const double&); // OK, specialization of g1<int, const double> â *end example*]
|
||
|
||
[22](#dcl.fct-22)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4190)
|
||
|
||
An abbreviated function template can have a [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]")[.](#dcl.fct-22.sentence-1)
|
||
|
||
The invented [*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]")*s* are
|
||
appended to the [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") after
|
||
the explicitly declared [*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s*[.](#dcl.fct-22.sentence-2)
|
||
|
||
[*Example [10](#dcl.fct-example-10)*: template<typename> concept C = /* ... */;
|
||
|
||
template <typename T, C U>void g(T x, U y, C auto z);
|
||
|
||
This is functionally equivalent to each of the following two declarations[.](#dcl.fct-22.sentence-3)
|
||
|
||
template<typename T, C U, C W>void g(T x, U y, W z);
|
||
|
||
template<typename T, typename U, typename W>requires C<U> && C<W>void g(T x, U y, W z); â *end example*]
|
||
|
||
[23](#dcl.fct-23)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4214)
|
||
|
||
A function declaration at block scope
|
||
shall not declare an abbreviated function template[.](#dcl.fct-23.sentence-1)
|
||
|
||
[24](#dcl.fct-24)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4218)
|
||
|
||
A [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") or [*abstract-declarator*](dcl.name#nt:abstract-declarator "9.3.2 Type names [dcl.name]") containing an ellipsis shall only
|
||
be used in a [*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]")[.](#dcl.fct-24.sentence-1)
|
||
|
||
When it is part of a[*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]"),
|
||
the [*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") declares a
|
||
function parameter pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#dcl.fct-24.sentence-2)
|
||
|
||
Otherwise, the [*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") is part of a[*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") and declares a
|
||
template parameter pack; see [[temp.param]](temp.param "13.2 Template parameters")[.](#dcl.fct-24.sentence-3)
|
||
|
||
A function parameter pack is a pack expansion ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#dcl.fct-24.sentence-4)
|
||
|
||
[*Example [11](#dcl.fct-example-11)*: template<typename... T> void f(T (* ...t)(int, int));
|
||
|
||
int add(int, int);float subtract(int, int);
|
||
|
||
void g() { f(add, subtract);} â *end example*]
|
||
|
||
[25](#dcl.fct-25)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4243)
|
||
|
||
There is a syntactic ambiguity when an ellipsis occurs at the end
|
||
of a [*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") without a preceding
|
||
comma[.](#dcl.fct-25.sentence-1)
|
||
|
||
In this case, the ellipsis is parsed as part of the[*abstract-declarator*](dcl.name#nt:abstract-declarator "9.3.2 Type names [dcl.name]") if the type of the parameter either names
|
||
a template parameter pack that has not been expanded or contains auto;
|
||
otherwise, it is
|
||
parsed as part of the [*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]")[.](#dcl.fct-25.sentence-2)[76](#footnote-76 "One can explicitly disambiguate the parse either by introducing a comma (so the ellipsis will be parsed as part of the parameter-declaration-clause) or by introducing a name for the parameter (so the ellipsis will be parsed as part of the declarator-id).")
|
||
|
||
[75)](#footnote-75)[75)](#footnoteref-75)
|
||
|
||
As indicated by syntax, cv-qualifiers are a significant component in function return types[.](#footnote-75.sentence-1)
|
||
|
||
[76)](#footnote-76)[76)](#footnoteref-76)
|
||
|
||
One can explicitly disambiguate the parse either by
|
||
introducing a comma (so the ellipsis will be parsed as part of the[*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]")) or by introducing a name for the
|
||
parameter (so the ellipsis will be parsed as part of the[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]"))[.](#footnote-76.sentence-1)
|
||
|
||
#### [9.3.4.7](#dcl.fct.default) Default arguments [[dcl.fct.default]](dcl.fct.default)
|
||
|
||
[1](#dcl.fct.default-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4263)
|
||
|
||
If an [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") is specified in a[*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") this[*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") is used as a default argument[.](#dcl.fct.default-1.sentence-1)
|
||
|
||
[*Note [1](#dcl.fct.default-note-1)*:
|
||
|
||
Default arguments will be used in calls
|
||
where trailing arguments are missing ([[expr.call]](expr.call "7.6.1.3 Function call"))[.](#dcl.fct.default-1.sentence-2)
|
||
|
||
â *end note*]
|
||
|
||
[2](#dcl.fct.default-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4273)
|
||
|
||
[*Example [1](#dcl.fct.default-example-1)*:
|
||
|
||
The declarationvoid point(int = 3, int = 4); declares a function that can be called with zero, one, or two arguments of typeint[.](#dcl.fct.default-2.sentence-1)
|
||
|
||
It can be called in any of these ways:point(1,2); point(1); point();
|
||
|
||
The last two calls are equivalent topoint(1,4) andpoint(3,4),
|
||
respectively[.](#dcl.fct.default-2.sentence-3)
|
||
|
||
â *end example*]
|
||
|
||
[3](#dcl.fct.default-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4294)
|
||
|
||
A default argument shall be specified only in the[*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") of a function declaration
|
||
or [*lambda-declarator*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") or in a[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]") ([[temp.param]](temp.param "13.2 Template parameters"))[.](#dcl.fct.default-3.sentence-1)
|
||
|
||
A default argument shall not be specified for
|
||
a template parameter pack or
|
||
a function parameter pack[.](#dcl.fct.default-3.sentence-2)
|
||
|
||
If it is specified in a[*parameter-declaration-clause*](#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]"),
|
||
it shall not occur within a[*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") or[*abstract-declarator*](dcl.name#nt:abstract-declarator "9.3.2 Type names [dcl.name]") of a[*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]")[.](#dcl.fct.default-3.sentence-3)[77](#footnote-77 "This means that default arguments cannot appear, for example, in declarations of pointers to functions, references to functions, or typedef declarations.")
|
||
|
||
[4](#dcl.fct.default-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4321)
|
||
|
||
For non-template functions, default arguments can be added in later
|
||
declarations of a
|
||
function that have the same host scope[.](#dcl.fct.default-4.sentence-1)
|
||
|
||
Declarations that have different
|
||
host scopes have completely distinct sets of default arguments[.](#dcl.fct.default-4.sentence-2)
|
||
|
||
That
|
||
is, declarations in inner scopes do not acquire default
|
||
arguments from declarations in outer scopes, and vice versa[.](#dcl.fct.default-4.sentence-3)
|
||
|
||
In
|
||
a given function declaration, each parameter subsequent to a
|
||
parameter with a default argument shall have a default argument
|
||
supplied in this or a previous declaration,
|
||
unless the parameter was expanded from a parameter pack,
|
||
or shall be a function parameter pack[.](#dcl.fct.default-4.sentence-4)
|
||
|
||
[*Note [2](#dcl.fct.default-note-2)*:
|
||
|
||
A default argument
|
||
cannot be redefined by a later declaration
|
||
(not even to the same value) ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule"))[.](#dcl.fct.default-4.sentence-5)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [2](#dcl.fct.default-example-2)*: void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow// a parameter with a default argumentvoid f(int, int);void f(int, int = 7);void h() { f(3); // OK, calls f(3, 7)void f(int = 1, int); // error: does not use default from surrounding scope}void m() {void f(int, int); // has no defaults f(4); // error: wrong number of argumentsvoid f(int, int = 5); // OK f(4); // OK, calls f(4, 5);void f(int, int = 5); // error: cannot redefine, even to same value}void n() { f(6); // OK, calls f(6, 7)}template<class ... T> struct C {void f(int n = 0, T...);};
|
||
C<int> c; // OK, instantiates declaration void C::f(int n = 0, int) â *end example*]
|
||
|
||
For a given inline function defined in different translation units,
|
||
the accumulated sets of default arguments at the end of the
|
||
translation units shall be the same; no diagnostic is required[.](#dcl.fct.default-4.sentence-6)
|
||
|
||
If a friend declaration D specifies a default argument expression,
|
||
that declaration shall be a definition and there shall be no other
|
||
declaration of the function or function template
|
||
which is reachable from D or from which D is reachable[.](#dcl.fct.default-4.sentence-7)
|
||
|
||
[5](#dcl.fct.default-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4375)
|
||
|
||
The default argument has the
|
||
same semantic constraints as the initializer in a
|
||
declaration of a variable of the parameter type, using the
|
||
copy-initialization semantics ([[dcl.init]](dcl.init "9.5 Initializers"))[.](#dcl.fct.default-5.sentence-1)
|
||
|
||
The names in the
|
||
default argument are looked up, and the semantic constraints are checked,
|
||
at the point where the default argument appears, except that
|
||
an immediate invocation ([[expr.const]](expr.const "7.7 Constant expressions")) that
|
||
is a potentially-evaluated subexpression ([[intro.execution]](intro.execution "6.10.1 Sequential execution")) of
|
||
the [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]") in a [*parameter-declaration*](#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") is
|
||
neither evaluated
|
||
nor checked for whether it is a constant expression at that point[.](#dcl.fct.default-5.sentence-2)
|
||
|
||
Name lookup and checking of semantic constraints for default
|
||
arguments of templated functions are performed as described in [[temp.inst]](temp.inst "13.9.2 Implicit instantiation")[.](#dcl.fct.default-5.sentence-3)
|
||
|
||
[*Example [3](#dcl.fct.default-example-3)*:
|
||
|
||
In the following code,g will be called with the valuef(2):int a = 1;int f(int);int g(int x = f(a)); // default argument: f(::a)void h() { a = 2; {int a = 3;
|
||
g(); // g(f(::a))}}
|
||
|
||
â *end example*]
|
||
|
||
[*Note [3](#dcl.fct.default-note-3)*:
|
||
|
||
A default argument is a complete-class context ([[class.mem]](class.mem "11.4 Class members"))[.](#dcl.fct.default-5.sentence-5)
|
||
|
||
Access checking applies to names in default arguments as
|
||
described in [[class.access]](class.access "11.8 Member access control")[.](#dcl.fct.default-5.sentence-6)
|
||
|
||
â *end note*]
|
||
|
||
[6](#dcl.fct.default-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4419)
|
||
|
||
Except for member functions of templated classes, the
|
||
default arguments in a member function definition that appears
|
||
outside of the class definition
|
||
are added to the set of default arguments provided by the
|
||
member function declaration in the class definition;
|
||
the program is ill-formed if a default constructor ([[class.default.ctor]](class.default.ctor "11.4.5.2 Default constructors")),
|
||
copy or move constructor ([[class.copy.ctor]](class.copy.ctor "11.4.5.3 Copy/move constructors")), or
|
||
copy or move assignment operator ([[class.copy.assign]](class.copy.assign "11.4.6 Copy/move assignment operator"))
|
||
is so declared[.](#dcl.fct.default-6.sentence-1)
|
||
|
||
Default arguments for a member function of a templated class
|
||
shall be specified on the initial declaration of the member
|
||
function within the templated class[.](#dcl.fct.default-6.sentence-2)
|
||
|
||
[*Example [4](#dcl.fct.default-example-4)*: class C {void f(int i = 3); void g(int i, int j = 99);};
|
||
|
||
void C::f(int i = 3) {} // error: default argument already specified in class scopevoid C::g(int i = 88, int j) {} // in this translation unit, C::g can be called with no arguments â *end example*]
|
||
|
||
[7](#dcl.fct.default-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4444)
|
||
|
||
[*Note [4](#dcl.fct.default-note-4)*:
|
||
|
||
A local variable cannot be odr-used ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule"))
|
||
in a default argument[.](#dcl.fct.default-7.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [5](#dcl.fct.default-example-5)*: void f() {int i; extern void g(int x = i); // errorextern void h(int x = sizeof(i)); // OK// ...} â *end example*]
|
||
|
||
[8](#dcl.fct.default-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4460)
|
||
|
||
[*Note [5](#dcl.fct.default-note-5)*:
|
||
|
||
The keywordthis cannot appear in a default argument of a member function;
|
||
see [[expr.prim.this]](expr.prim.this "7.5.3 This")[.](#dcl.fct.default-8.sentence-1)
|
||
|
||
[*Example [6](#dcl.fct.default-example-6)*: class A {void f(A* p = this) { } // error}; â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
[9](#dcl.fct.default-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4475)
|
||
|
||
A default argument is evaluated each time the function is called
|
||
with no argument for the corresponding parameter[.](#dcl.fct.default-9.sentence-1)
|
||
|
||
A parameter shall not appear as a potentially-evaluated expression
|
||
in a default argument[.](#dcl.fct.default-9.sentence-2)
|
||
|
||
[*Note [6](#dcl.fct.default-note-6)*:
|
||
|
||
Parameters of a function declared before a default argument
|
||
are in scope and can hide namespace and class member names[.](#dcl.fct.default-9.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
[*Example [7](#dcl.fct.default-example-7)*: int a;int f(int a, int b = a); // error: parameter a used as default argumenttypedef int I;int g(float I, int b = I(2)); // error: parameter I foundint h(int a, int b = sizeof(a)); // OK, [unevaluated operand](expr.context#def:unevaluated_operand "7.2.3 Context dependence [expr.context]") â *end example*]
|
||
|
||
A non-static member shall not be designated in a default argument unless
|
||
|
||
- [(9.1)](#dcl.fct.default-9.1)
|
||
|
||
it is designated by
|
||
the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") or [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") of a class member access expression ([[expr.ref]](expr.ref "7.6.1.5 Class member access")),
|
||
|
||
- [(9.2)](#dcl.fct.default-9.2)
|
||
|
||
it is designated by an expression
|
||
used to form a pointer to member ([[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators")), or
|
||
|
||
- [(9.3)](#dcl.fct.default-9.3)
|
||
|
||
it appears as the operand of
|
||
a [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") ([[expr.reflect]](expr.reflect "7.6.2.10 The reflection operator"))[.](#dcl.fct.default-9.sentence-4)
|
||
|
||
[*Example [8](#dcl.fct.default-example-8)*:
|
||
|
||
The declaration ofX::mem1() in the following example is ill-formed because no object is supplied for the
|
||
non-static memberX::a used as an initializer[.](#dcl.fct.default-9.sentence-5)
|
||
|
||
int b;class X {int a; int mem1(int i = a); // error: non-static member a used as default argumentint mem2(int i = b); // OK, use X::bconsteval void mem3(std::meta::info r = ^^a) {} // OKint mem4(int i = [:^^a:]); // error: non-static member a designated in default argumentstatic int b;};
|
||
|
||
The declaration ofX::mem2() is meaningful, however, since no object is needed to access the static memberX::b[.](#dcl.fct.default-9.sentence-6)
|
||
|
||
Classes, objects, and members are described in [[class]](class "11 Classes")[.](#dcl.fct.default-9.sentence-7)
|
||
|
||
â *end example*]
|
||
|
||
A default argument is not part of the
|
||
type of a function[.](#dcl.fct.default-9.sentence-8)
|
||
|
||
[*Example [9](#dcl.fct.default-example-9)*: int f(int = 0);
|
||
|
||
void h() {int j = f(1); int k = f(); // OK, means f(0)}int (*p1)(int) = &f;int (*p2)() = &f; // error: type mismatch â *end example*]
|
||
|
||
[*Note [7](#dcl.fct.default-note-7)*:
|
||
|
||
When an overload set contains a declaration of a function
|
||
whose host scope is S,
|
||
any default argument associated with any reachable declaration
|
||
whose host scope is S is available to the call ([[over.match.viable]](over.match.viable "12.2.3 Viable functions"))[.](#dcl.fct.default-9.sentence-9)
|
||
|
||
â *end note*]
|
||
|
||
[*Note [8](#dcl.fct.default-note-8)*:
|
||
|
||
The candidate might have been found through a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") from which the declaration that provides the default argument is not reachable[.](#dcl.fct.default-9.sentence-10)
|
||
|
||
â *end note*]
|
||
|
||
[10](#dcl.fct.default-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L4560)
|
||
|
||
A virtual function call ([[class.virtual]](class.virtual "11.7.3 Virtual functions")) uses the default
|
||
arguments in the declaration of the virtual function determined
|
||
by the static type of the pointer or reference denoting the
|
||
object[.](#dcl.fct.default-10.sentence-1)
|
||
|
||
An overriding function in a derived class does not
|
||
acquire default arguments from the function it overrides[.](#dcl.fct.default-10.sentence-2)
|
||
|
||
[*Example [10](#dcl.fct.default-example-10)*: struct A {virtual void f(int a = 7);};struct B : public A {void f(int a);};void m() { B* pb = new B;
|
||
A* pa = pb;
|
||
pa->f(); // OK, calls pa->B::f(7) pb->f(); // error: wrong number of arguments for B::f()} â *end example*]
|
||
|
||
[77)](#footnote-77)[77)](#footnoteref-77)
|
||
|
||
This means that default
|
||
arguments cannot appear,
|
||
for example, in declarations of pointers to functions,
|
||
references to functions, ortypedef declarations[.](#footnote-77.sentence-1)
|