11 KiB
[dcl.decl.general]
9 Declarations [dcl]
9.3 Declarators [dcl.decl]
9.3.1 General [dcl.decl.general]
A declarator declares a single variable, function, or type, within a declaration.
Theinit-declarator-list appearing in a simple-declaration is a comma-separated sequence of declarators, each of which can have an initializer.
init-declarator-list:
init-declarator
init-declarator-list , init-declarator
init-declarator:
declarator initializer
declarator requires-clauseopt function-contract-specifier-seqopt
In all contexts, a declarator is interpreted as given below.
Where an abstract-declarator can be used (or omitted) in place of a declarator ([dcl.fct], [except.pre]), it is as if a unique identifier were included in the appropriate place ([dcl.name]).
The preceding specifiers indicate the type, storage duration, linkage, or other properties of the entity or entities being declared.
Each declarator specifies one entity and (optionally) names it and/or modifies the type of the specifiers with operators such as* (pointer to) and () (function returning).
[Note 1:
An init-declarator can also specify an initializer ([dcl.init]).
â end note]
Each init-declarator or member-declarator in a declaration is analyzed separately as if it were in a declaration by itself.
[Note 2:
A declaration with several declarators is usually equivalent to the corresponding sequence of declarations each with a single declarator.
That is,T D1, D2, ... Dn; is usually equivalent toT D1; T D2; ... T Dn; where T is a decl-specifier-seq and each Di is an init-declarator or member-declarator.
One exception is when a name introduced by one of thedeclarators hides a type name used by thedecl-specifiers, so that when the samedecl-specifiers are used in a subsequent declaration, they do not have the same meaning, as instruct S { /* ... / }; S S, T; // declare two instances of struct S which is not equivalent tostruct S { / ... */ }; S S; S T; // error
Another exception is when T is auto ([dcl.spec.auto]), for example:auto i = 1, j = 2.0; // error: deduced types for i and j do not match as opposed toauto i = 1; // OK, i deduced to have type intauto j = 2.0; // OK, j deduced to have type double
â end note]
The optional requires-clause in aninit-declarator or member-declarator shall be present only if the declarator declares a templated function ([temp.pre]).
When present after a declarator, the requires-clause is called the trailing requires-clause.
The trailing requires-clause introduces theconstraint-expression that results from interpreting its constraint-logical-or-expression as aconstraint-expression.
[Example 1: void f1(int a) requires true; // error: non-templated functiontemplateauto f2(T a) -> bool requires true; // OKtemplateauto f3(T a) requires true -> bool; // error: requires-clause precedes trailing-return-typevoid (pf)() requires true; // error: constraint on a variablevoid g(int ()() requires true); // error: constraint on a parameter-declarationauto* p = new void(*)(char) requires true; // error: not a function declaration â end example]
The optional function-contract-specifier-seq ([dcl.contract.func]) in an init-declarator shall be present only if the declarator declares a function.
Declarators have the syntax
declarator:
ptr-declarator
noptr-declarator parameters-and-qualifiers trailing-return-type
ptr-declarator:
noptr-declarator
ptr-operator ptr-declarator
noptr-declarator:
declarator-id attribute-specifier-seqopt
noptr-declarator parameters-and-qualifiers
noptr-declarator [ constant-expressionopt ] attribute-specifier-seqopt
( ptr-declarator )
parameters-and-qualifiers:
( parameter-declaration-clause ) cv-qualifier-seqopt
ref-qualifieropt noexcept-specifieropt attribute-specifier-seqopt
trailing-return-type:
-> type-id
- attribute-specifier-seqopt cv-qualifier-seqopt
& attribute-specifier-seqopt
&& attribute-specifier-seqopt
nested-name-specifier * attribute-specifier-seqopt cv-qualifier-seqopt
cv-qualifier-seq:
cv-qualifier cv-qualifier-seqopt
cv-qualifier:
const
volatile
ref-qualifier:
&
&&
declarator-id:
...opt id-expression