%!TEX root = std.tex \rSec0[dcl.dcl]{Declarations}% \indextext{declaration|(} \gramSec[gram.dcl]{Declarations} \indextext{linkage specification|see{specification, linkage}} \rSec1[dcl.pre]{Preamble} \pnum Declarations generally specify how names are to be interpreted. Declarations have the form \begin{bnf} \nontermdef{declaration-seq}\br declaration\br declaration-seq declaration \end{bnf} \begin{bnf} \nontermdef{declaration}\br name-declaration\br special-declaration \end{bnf} \begin{bnf} \nontermdef{name-declaration}\br block-declaration\br nodeclspec-function-declaration\br function-definition\br template-declaration\br deduction-guide\br linkage-specification\br namespace-definition\br empty-declaration\br attribute-declaration\br module-import-declaration \end{bnf} \begin{bnf} \nontermdef{special-declaration}\br explicit-instantiation\br explicit-specialization\br export-declaration \end{bnf} \begin{bnf} \nontermdef{block-declaration}\br simple-declaration\br asm-declaration\br namespace-alias-definition\br using-declaration\br using-enum-declaration\br using-directive\br static_assert-declaration\br alias-declaration\br opaque-enum-declaration \end{bnf} \begin{bnf} \nontermdef{nodeclspec-function-declaration}\br \opt{attribute-specifier-seq} declarator \terminal{;} \end{bnf} \begin{bnf} \nontermdef{alias-declaration}\br \keyword{using} identifier \opt{attribute-specifier-seq} \terminal{=} defining-type-id \terminal{;} \end{bnf} \begin{bnf} \nontermdef{simple-declaration}\br decl-specifier-seq \opt{init-declarator-list} \terminal{;}\br attribute-specifier-seq decl-specifier-seq init-declarator-list \terminal{;}\br \opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \terminal{[} identifier-list \terminal{]} initializer \terminal{;} \end{bnf} \begin{bnf} \nontermdef{static_assert-declaration}\br \keyword{static_assert} \terminal{(} constant-expression \terminal{)} \terminal{;}\br \keyword{static_assert} \terminal{(} constant-expression \terminal{,} string-literal \terminal{)} \terminal{;} \end{bnf} \begin{bnf} \nontermdef{empty-declaration}\br \terminal{;} \end{bnf} \begin{bnf} \nontermdef{attribute-declaration}\br attribute-specifier-seq \terminal{;} \end{bnf} \begin{note} \grammarterm{asm-declaration}{s} are described in~\ref{dcl.asm}, and \grammarterm{linkage-specification}{s} are described in~\ref{dcl.link}; \grammarterm{function-definition}{s} are described in~\ref{dcl.fct.def} and \grammarterm{template-declaration}{s} and \grammarterm{deduction-guide}{s} are described in \ref{temp.deduct.guide}; \grammarterm{namespace-definition}{s} are described in~\ref{namespace.def}, \grammarterm{using-declaration}{s} are described in~\ref{namespace.udecl} and \grammarterm{using-directive}{s} are described in~\ref{namespace.udir}. \end{note} \pnum \indextext{declaration}% \indextext{scope}% Certain declarations contain one or more scopes\iref{basic.scope.scope}. Unless otherwise stated, utterances in \ref{dcl.dcl} about components in, of, or contained by a declaration or subcomponent thereof refer only to those components of the declaration that are \emph{not} nested within scopes nested within the declaration. \pnum A \grammarterm{simple-declaration} or \grammarterm{nodeclspec-function-declaration} of the form \begin{ncsimplebnf} \opt{attribute-specifier-seq} \opt{decl-specifier-seq} \opt{init-declarator-list} \terminal{;} \end{ncsimplebnf} is divided into three parts. Attributes are described in~\ref{dcl.attr}. \grammarterm{decl-specifier}{s}, the principal components of a \grammarterm{decl-specifier-seq}, are described in~\ref{dcl.spec}. \grammarterm{declarator}{s}, the components of an \grammarterm{init-declarator-list}, are described in \ref{dcl.decl}. The \grammarterm{attribute-specifier-seq} appertains to each of the entities declared by the \grammarterm{declarator}{s} of the \grammarterm{init-declarator-list}. \begin{note} In the declaration for an entity, attributes appertaining to that entity can appear at the start of the declaration and after the \grammarterm{declarator-id} for that declaration. \end{note} \begin{example} \begin{codeblock} [[noreturn]] void f [[noreturn]] (); // OK \end{codeblock} \end{example} \pnum If a \grammarterm{declarator-id} is a name, the \grammarterm{init-declarator} and (hence) the declaration introduce that name. \begin{note} Otherwise, the \grammarterm{declarator-id} is a \grammarterm{qualified-id} or names a destructor or its \grammarterm{unqualified-id} is a \grammarterm{template-id} and no name is introduced. \end{note} The \grammarterm{defining-type-specifier}{s}\iref{dcl.type} in the \grammarterm{decl-specifier-seq} and the recursive \grammarterm{declarator} structure describe a type\iref{dcl.meaning}, which is then associated with the \grammarterm{declarator-id}. \pnum \indextext{identifier}% \indextext{declarator}% In a \grammarterm{simple-declaration}, the optional \grammarterm{init-declarator-list} can be omitted only when declaring a class\iref{class.pre} or enumeration\iref{dcl.enum}, that is, when the \grammarterm{decl-specifier-seq} contains either a \grammarterm{class-specifier}, an \grammarterm{elaborated-type-specifier} with a \grammarterm{class-key}\iref{class.name}, or an \grammarterm{enum-specifier}. In these cases and whenever a \grammarterm{class-specifier} or \grammarterm{enum-specifier} is present in the \grammarterm{decl-specifier-seq}, the identifiers in these specifiers are also declared (as \grammarterm{class-name}{s}, \grammarterm{enum-name}{s}, or \grammarterm{enumerator}{s}, depending on the syntax). In such cases, the \grammarterm{decl-specifier-seq} shall (re)introduce one or more names into the program. \begin{example} \begin{codeblock} enum { }; // error typedef class { }; // error \end{codeblock} \end{example} \pnum A \grammarterm{simple-declaration} with an \grammarterm{identifier-list} is called a \defn{structured binding declaration}\iref{dcl.struct.bind}. Each \grammarterm{decl-specifier} in the \grammarterm{decl-specifier-seq} shall be \tcode{static}, \tcode{thread_local}, \tcode{auto}\iref{dcl.spec.auto}, or a \grammarterm{cv-qualifier}. \begin{example} \begin{codeblock} template concept C = true; C auto [x, y] = std::pair{1, 2}; // error: constrained \grammarterm{placeholder-type-specifier} // not permitted for structured bindings \end{codeblock} \end{example} The \grammarterm{initializer} shall be of the form ``\tcode{=} \grammarterm{assignment-expression}'', of the form ``\tcode{\{} \grammarterm{assignment-expression} \tcode{\}}'', or of the form ``\tcode{(} \grammarterm{assignment-expression} \tcode{)}'', where the \grammarterm{assignment-expression} is of array or non-union class type. \pnum If the \grammarterm{decl-specifier-seq} contains the \keyword{typedef} specifier, the declaration is a \defnx{typedef declaration}{declaration!typedef} and each \grammarterm{declarator-id} is declared to be a \grammarterm{typedef-name}, synonymous with its associated type\iref{dcl.typedef}. \begin{note} Such a \grammarterm{declarator-id} is an \grammarterm{identifier}\iref{class.conv.fct}. \end{note} Otherwise, if the type associated with a \grammarterm{declarator-id} is a function type\iref{dcl.fct}, the declaration is a \defnx{function declaration}{declaration!function}. Otherwise, if the type associated with a \grammarterm{declarator-id} is an object or reference type, the declaration is an \defnx{object declaration}{declaration!object}. Otherwise, the program is ill-formed. \begin{example} \begin{codeblock} int f(), x; // OK, function declaration for \tcode{f} and object declaration for \tcode{x} extern void g(), // OK, function declaration for \tcode{g} y; // error: \tcode{void} is not an object type \end{codeblock} \end{example} \pnum \indextext{definition!declaration as}% Syntactic components beyond those found in the general form of \grammarterm{simple-declaration} are added to a function declaration to make a \grammarterm{function-definition}. An object declaration, however, is also a definition unless it contains the \keyword{extern} specifier and has no initializer\iref{basic.def}. \indextext{initialization!definition and}% An object definition causes storage of appropriate size and alignment to be reserved and any appropriate initialization\iref{dcl.init} to be done. \pnum A \grammarterm{nodeclspec-function-declaration} shall declare a constructor, destructor, or conversion function. \begin{note} Because a member function cannot be subject to a non-defining declaration outside of a class definition\iref{class.mfct}, a \grammarterm{nodeclspec-function-declaration} can only be used in a \grammarterm{template-declaration}\iref{temp.pre}, \grammarterm{explicit-instantiation}\iref{temp.explicit}, or \grammarterm{explicit-specialization}\iref{temp.expl.spec}. \end{note} \pnum \indextext{\idxcode{static_assert}}% In a \grammarterm{static_assert-declaration}, the \grammarterm{constant-expression} is contextually converted to \keyword{bool} and the converted expression shall be a constant expression\iref{expr.const}. If the value of the expression when so converted is \tcode{true} or the expression is evaluated in the context of a template definition, the declaration has no effect. Otherwise, the \grammarterm{static_assert-declaration} \defnx{fails}{\idxcode{static_assert}!failed}, the program is ill-formed, and the resulting diagnostic message\iref{intro.compliance} should include the text of the \grammarterm{string-literal}, if one is supplied. \begin{example} \begin{codeblock} static_assert(sizeof(int) == sizeof(void*), "wrong pointer size"); static_assert(sizeof(int[2])); // OK, narrowing allowed template void f(T t) { if constexpr (sizeof(T) == sizeof(int)) { use(t); } else { static_assert(false, "must be int-sized"); } } void g(char c) { f(0); // OK f(c); // error on implementations where \tcode{sizeof(int) > 1}: must be \tcode{int}-sized } \end{codeblock} \end{example} \pnum An \grammarterm{empty-declaration} has no effect. \pnum Except where otherwise specified, the meaning of an \grammarterm{attribute-declaration} is \impldef{meaning of attribute declaration}. \rSec1[dcl.spec]{Specifiers}% \rSec2[dcl.spec.general]{General}% \indextext{specifier|(} \pnum \indextext{specifier!declaration}% The specifiers that can be used in a declaration are \begin{bnf} \nontermdef{decl-specifier}\br storage-class-specifier\br defining-type-specifier\br function-specifier\br \keyword{friend}\br \keyword{typedef}\br \keyword{constexpr}\br \keyword{consteval}\br \keyword{constinit}\br \keyword{inline} \end{bnf} \begin{bnf} \nontermdef{decl-specifier-seq}\br decl-specifier \opt{attribute-specifier-seq}\br decl-specifier decl-specifier-seq \end{bnf} The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{decl-specifier-seq} appertains to the type determined by the preceding \grammarterm{decl-specifier}{s}\iref{dcl.meaning}. The \grammarterm{attribute-specifier-seq} affects the type only for the declaration it appears in, not other declarations involving the same type. \pnum Each \grammarterm{decl-specifier} shall appear at most once in a complete \grammarterm{decl-specifier-seq}, except that \tcode{long} may appear twice. At most one of the \keyword{constexpr}, \keyword{consteval}, and \keyword{constinit} keywords shall appear in a \grammarterm{decl-specifier-seq}. \pnum \indextext{ambiguity!declaration type}% If a \grammarterm{type-name} is encountered while parsing a \grammarterm{decl-specifier-seq}, it is interpreted as part of the \grammarterm{decl-specifier-seq} if and only if there is no previous \grammarterm{defining-type-specifier} other than a \grammarterm{cv-qualifier} in the \grammarterm{decl-specifier-seq}. The sequence shall be self-consistent as described below. \begin{example} \begin{codeblock} typedef char* Pc; static Pc; // error: name missing \end{codeblock} Here, the declaration \keyword{static} \tcode{Pc} is ill-formed because no name was specified for the static variable of type \tcode{Pc}. To get a variable called \tcode{Pc}, a \grammarterm{type-specifier} (other than \keyword{const} or \tcode{volatile}) has to be present to indicate that the \grammarterm{typedef-name} \tcode{Pc} is the name being (re)declared, rather than being part of the \grammarterm{decl-specifier} sequence. For another example, \begin{codeblock} void f(const Pc); // \tcode{void f(char* const)} (not \tcode{const char*}) void g(const int Pc); // \tcode{void g(const int)} \end{codeblock} \end{example} \pnum \indextext{\idxcode{signed}!typedef@\tcode{typedef} and}% \indextext{\idxcode{unsigned}!typedef@\tcode{typedef} and}% \indextext{\idxcode{long}!typedef@\tcode{typedef} and}% \indextext{\idxcode{short}!typedef@\tcode{typedef} and}% \begin{note} Since \tcode{signed}, \tcode{unsigned}, \tcode{long}, and \tcode{short} by default imply \tcode{int}, a \grammarterm{type-name} appearing after one of those specifiers is treated as the name being (re)declared. \begin{example} \begin{codeblock} void h(unsigned Pc); // \tcode{void h(unsigned int)} void k(unsigned int Pc); // \tcode{void k(unsigned int)} \end{codeblock} \end{example} \end{note} \rSec2[dcl.stc]{Storage class specifiers}% \indextext{specifier!storage class}% \indextext{declaration!storage class}% \indextext{\idxcode{static}}% \indextext{\idxcode{thread_local}}% \indextext{\idxcode{extern}}% \indextext{\idxcode{mutable}} \pnum The storage class specifiers are \begin{bnf} \nontermdef{storage-class-specifier}\br \keyword{static}\br \keyword{thread_local}\br \keyword{extern}\br \keyword{mutable} \end{bnf} At most one \grammarterm{storage-class-specifier} shall appear in a given \grammarterm{decl-specifier-seq}, except that \keyword{thread_local} may appear with \keyword{static} or \keyword{extern}. If \keyword{thread_local} appears in any declaration of a variable it shall be present in all declarations of that entity. If a \grammarterm{storage-class-specifier} appears in a \grammarterm{decl-specifier-seq}, there can be no \tcode{typedef} specifier in the same \grammarterm{decl-specifier-seq} and the \grammarterm{init-declarator-list} or \grammarterm{member-declarator-list} of the declaration shall not be empty (except for an anonymous union declared in a namespace scope\iref{class.union.anon}). The \grammarterm{storage-class-specifier} applies to the name declared by each \grammarterm{init-declarator} in the list and not to any names declared by other specifiers. \begin{note} See \ref{temp.expl.spec} and \ref{temp.explicit} for restrictions in explicit specializations and explicit instantiations, respectively. \end{note} \pnum \begin{note} A variable declared without a \grammarterm{storage-class-specifier} at block scope or declared as a function parameter has automatic storage duration by default\iref{basic.stc.auto}. \end{note} \pnum The \keyword{thread_local} specifier indicates that the named entity has thread storage duration\iref{basic.stc.thread}. It shall be applied only to the declaration of a variable of namespace or block scope, to a structured binding declaration\iref{dcl.struct.bind}, or to the declaration of a static data member. When \keyword{thread_local} is applied to a variable of block scope the \grammarterm{storage-class-specifier} \keyword{static} is implied if no other \grammarterm{storage-class-specifier} appears in the \grammarterm{decl-specifier-seq}. \pnum \indextext{restriction!\idxcode{static}}% The \keyword{static} specifier shall be applied only to the declaration of a variable or function, to a structured binding declaration\iref{dcl.struct.bind}, or to the declaration of an anonymous union\iref{class.union.anon}. There can be no \keyword{static} function declarations within a block, nor any \keyword{static} function parameters. A \tcode{static} specifier used in the declaration of a variable declares the variable to have static storage duration\iref{basic.stc.static}, unless accompanied by the \keyword{thread_local} specifier, which declares the variable to have thread storage duration\iref{basic.stc.thread}. A \keyword{static} specifier can be used in declarations of class members;~\ref{class.static} describes its effect. \indextext{\idxcode{static}!linkage of}% For the linkage of a name declared with a \keyword{static} specifier, see~\ref{basic.link}. \pnum \indextext{restriction!\idxcode{extern}}% The \keyword{extern} specifier shall be applied only to the declaration of a variable or function. The \keyword{extern} specifier shall not be used in the declaration of a class member or function parameter. \indextext{\idxcode{extern}!linkage of}% \indextext{consistency!linkage}% For the linkage of a name declared with an \keyword{extern} specifier, see~\ref{basic.link}. \begin{note} The \keyword{extern} keyword can also be used in \grammarterm{explicit-instantiation}{s} and \grammarterm{linkage-specification}{s}, but it is not a \grammarterm{storage-class-specifier} in such contexts. \end{note} \pnum All declarations for a given entity shall give its name the same linkage. \begin{note} The linkage given by some declarations is affected by previous declarations. Overloads are distinct entities. \end{note} \begin{example} \begin{codeblock} static char* f(); // \tcode{f()} has internal linkage char* f() // \tcode{f()} still has internal linkage { @\commentellip@ } char* g(); // \tcode{g()} has external linkage static char* g() // error: inconsistent linkage { @\commentellip@ } void h(); inline void h(); // external linkage inline void l(); void l(); // external linkage inline void m(); extern void m(); // external linkage static void n(); inline void n(); // internal linkage static int a; // \tcode{a} has internal linkage int a; // error: two definitions static int b; // \tcode{b} has internal linkage extern int b; // \tcode{b} still has internal linkage int c; // \tcode{c} has external linkage static int c; // error: inconsistent linkage extern int d; // \tcode{d} has external linkage static int d; // error: inconsistent linkage \end{codeblock} \end{example} \pnum \indextext{declaration!forward}% The name of a declared but undefined class can be used in an \keyword{extern} declaration. Such a declaration can only be used in ways that do not require a complete class type. \begin{example} \begin{codeblock} struct S; extern S a; extern S f(); extern void g(S); void h() { g(a); // error: \tcode{S} is incomplete f(); // error: \tcode{S} is incomplete } \end{codeblock} \end{example} \pnum The \keyword{mutable} specifier shall appear only in the declaration of a non-static data member\iref{class.mem} whose type is neither const-qualified nor a reference type. \begin{example} \begin{codeblock} class X { mutable const int* p; // OK mutable int* const q; // error }; \end{codeblock} \end{example} \pnum \begin{note} The \keyword{mutable} specifier on a class data member nullifies a \keyword{const} specifier applied to the containing class object and permits modification of the mutable class member even though the rest of the object is const\iref{basic.type.qualifier,dcl.type.cv}. \end{note} \rSec2[dcl.fct.spec]{Function specifiers}% \indextext{specifier!function}% \indextext{function|seealso{friend function}} \indextext{function|seealso{member function}} \indextext{function|seealso{inline function}} \indextext{function|seealso{virtual function}} \pnum A \grammarterm{function-specifier} can be used only in a function declaration. \begin{bnf} \nontermdef{function-specifier}\br \keyword{virtual}\br explicit-specifier \end{bnf} \begin{bnf} \nontermdef{explicit-specifier}\br \keyword{explicit} \terminal{(} constant-expression \terminal{)}\br \keyword{explicit} \end{bnf} \pnum \indextext{specifier!\idxcode{virtual}}% The \keyword{virtual} specifier shall be used only in the initial declaration of a non-static member function; see~\ref{class.virtual}. \pnum \indextext{specifier!\idxcode{explicit}}% An \grammarterm{explicit-specifier} shall be used only in the declaration of a constructor or conversion function within its class definition; see~\ref{class.conv.ctor} and~\ref{class.conv.fct}. \pnum In an \grammarterm{explicit-specifier}, the \grammarterm{constant-expression}, if supplied, shall be a contextually converted constant expression of type \tcode{bool}\iref{expr.const}. The \grammarterm{explicit-specifier} \keyword{explicit} without a \grammarterm{constant-expression} is equivalent to the \grammarterm{explicit-specifier} \tcode{explicit(true)}. If the constant expression evaluates to \tcode{true}, the function is explicit. Otherwise, the function is not explicit. A \tcode{(} token that follows \keyword{explicit} is parsed as part of the \grammarterm{explicit-specifier}. \begin{example} \begin{codeblock} struct S { explicit(sizeof(char[2])) S(char); // error: narrowing conversion of value 2 to type \keyword{bool} explicit(sizeof(char)) S(bool); // OK, conversion of value 1 to type \keyword{bool} is non-narrowing }; \end{codeblock} \end{example} \rSec2[dcl.typedef]{The \keyword{typedef} specifier}% \indextext{specifier!\idxcode{typedef}} \pnum Declarations containing the \grammarterm{decl-specifier} \keyword{typedef} declare identifiers that can be used later for naming fundamental\iref{basic.fundamental} or compound\iref{basic.compound} types. The \keyword{typedef} specifier shall not be combined in a \grammarterm{decl-specifier-seq} with any other kind of specifier except a \grammarterm{defining-type-specifier}, and it shall not be used in the \grammarterm{decl-specifier-seq} of a \grammarterm{parameter-declaration}\iref{dcl.fct} nor in the \grammarterm{decl-specifier-seq} of a \grammarterm{function-definition}\iref{dcl.fct.def}. If a \keyword{typedef} specifier appears in a declaration without a \grammarterm{declarator}, the program is ill-formed. \begin{bnf} \nontermdef{typedef-name}\br identifier\br simple-template-id \end{bnf} A name declared with the \keyword{typedef} specifier becomes a \grammarterm{typedef-name}. A \grammarterm{typedef-name} names the type associated with the \grammarterm{identifier}\iref{dcl.decl} or \grammarterm{simple-template-id}\iref{temp.pre}; \indextext{declaration!typedef@\tcode{typedef} as type}% \indextext{equivalence!type}% \indextext{synonym!type name as}% a \grammarterm{typedef-name} is thus a synonym for another type. A \grammarterm{typedef-name} does not introduce a new type the way a class declaration\iref{class.name} or enum declaration\iref{dcl.enum} does. \begin{example} After \begin{codeblock} typedef int MILES, *KLICKSP; \end{codeblock} the constructions \begin{codeblock} MILES distance; extern KLICKSP metricp; \end{codeblock} are all correct declarations; the type of \tcode{distance} is \tcode{int} and that of \tcode{metricp} is ``pointer to \tcode{int}''. \end{example} \pnum A \grammarterm{typedef-name} can also be introduced by an \grammarterm{alias-declaration}. The \grammarterm{identifier} following the \tcode{using} keyword is not looked up; it becomes a \grammarterm{typedef-name} and the optional \grammarterm{attribute-specifier-seq} following the \grammarterm{identifier} appertains to that \grammarterm{typedef-name}. Such a \grammarterm{typedef-name} has the same semantics as if it were introduced by the \keyword{typedef} specifier. In particular, it does not define a new type. \begin{example} \begin{codeblock} using handler_t = void (*)(int); extern handler_t ignore; extern void (*ignore)(int); // redeclare \tcode{ignore} template struct P { }; using cell = P; // error: \tcode{cell} not found\iref{basic.scope.pdecl} \end{codeblock} \end{example} The \grammarterm{defining-type-specifier-seq} of the \grammarterm{defining-type-id} shall not define a class or enumeration if the \grammarterm{alias-declaration} is the \grammarterm{declaration} of a \grammarterm{template-declaration}. \pnum \indextext{class name!\idxcode{typedef}}% A \grammarterm{simple-template-id} is only a \grammarterm{typedef-name} if its \grammarterm{template-name} names an alias template or a template \grammarterm{template-parameter}. \begin{note} A \grammarterm{simple-template-id} that names a class template specialization is a \grammarterm{class-name}\iref{class.name}. If a \grammarterm{typedef-name} is used to identify the subject of an \grammarterm{elaborated-type-specifier}\iref{dcl.type.elab}, a class definition\iref{class}, a constructor declaration\iref{class.ctor}, or a destructor declaration\iref{class.dtor}, the program is ill-formed. \end{note} \begin{example} \begin{codeblock} struct S { S(); ~S(); }; typedef struct S T; S a = T(); // OK struct T * p; // error \end{codeblock} \end{example} \pnum \indextext{class name!\idxcode{typedef}}% \indextext{enum name!\idxcode{typedef}}% \indextext{class!unnamed}% An unnamed class or enumeration $C$ defined in a typedef declaration has the first \grammarterm{typedef-name} declared by the declaration to be of type $C$ as its \defn{typedef name for linkage purposes}\iref{basic.link}. \begin{note} A typedef declaration involving a \grammarterm{lambda-expression} does not itself define the associated closure type, and so the closure type is not given a typedef name for linkage purposes. \end{note} \begin{example} \begin{codeblock} typedef struct { } *ps, S; // \tcode{S} is the typedef name for linkage purposes typedef decltype([]{}) C; // the closure type has no typedef name for linkage purposes \end{codeblock} \end{example} \pnum An unnamed class with a typedef name for linkage purposes shall not \begin{itemize} \item declare any members other than non-static data members, member enumerations, or member classes, \item have any base classes or default member initializers, or \item contain a \grammarterm{lambda-expression}, \end{itemize} and all member classes shall also satisfy these requirements (recursively). \begin{example} \begin{codeblock} typedef struct { int f() {} } X; // error: struct with typedef name for linkage has member functions \end{codeblock} \end{example} \rSec2[dcl.friend]{The \keyword{friend} specifier}% \indextext{specifier!\idxcode{friend}} \pnum The \keyword{friend} specifier is used to specify access to class members; see~\ref{class.friend}. \rSec2[dcl.constexpr]{The \keyword{constexpr} and \keyword{consteval} specifiers}% \indextext{specifier!\idxcode{constexpr}} \indextext{specifier!\idxcode{consteval}} \pnum The \keyword{constexpr} specifier shall be applied only to the definition of a variable or variable template or the declaration of a function or function template. The \keyword{consteval} specifier shall be applied only to the declaration of a function or function template. A function or static data member declared with the \keyword{constexpr} or \keyword{consteval} specifier is implicitly an inline function or variable\iref{dcl.inline}. If any declaration of a function or function template has a \keyword{constexpr} or \keyword{consteval} specifier, then all its declarations shall contain the same specifier. \begin{note} An explicit specialization can differ from the template declaration with respect to the \keyword{constexpr} or \keyword{consteval} specifier. \end{note} \begin{note} Function parameters cannot be declared \keyword{constexpr}. \end{note} \begin{example} \begin{codeblock} constexpr void square(int &x); // OK, declaration constexpr int bufsz = 1024; // OK, definition constexpr struct pixel { // error: \tcode{pixel} is a type int x; int y; constexpr pixel(int); // OK, declaration }; constexpr pixel::pixel(int a) : x(a), y(x) // OK, definition { square(x); } constexpr pixel small(2); // error: \tcode{square} not defined, so \tcode{small(2)} // not constant\iref{expr.const} so \keyword{constexpr} not satisfied constexpr void square(int &x) { // OK, definition x *= x; } constexpr pixel large(4); // OK, \tcode{square} defined int next(constexpr int x) { // error: not for parameters return x + 1; } extern constexpr int memsz; // error: not a definition \end{codeblock} \end{example} \pnum A \keyword{constexpr} or \keyword{consteval} specifier used in the declaration of a function declares that function to be a \defnx{constexpr function}{specifier!\idxcode{constexpr}!function}. \begin{note} A function or constructor declared with the \keyword{consteval} specifier is an immediate function\iref{expr.const}. \end{note} A destructor, an allocation function, or a deallocation function shall not be declared with the \keyword{consteval} specifier. \pnum \indextext{specifier!\idxcode{constexpr}!function}% \indextext{constexpr function}% A function is \defn{constexpr-suitable} if: \begin{itemize} \item it is not a coroutine\iref{dcl.fct.def.coroutine}, and \item if the function is a constructor or destructor, its class does not have any virtual base classes. \end{itemize} Except for instantiated constexpr functions, non-templated constexpr functions shall be constexpr-suitable. \begin{example} \begin{codeblock} constexpr int square(int x) { return x * x; } // OK constexpr long long_max() { return 2147483647; } // OK constexpr int abs(int x) { if (x < 0) x = -x; return x; // OK } constexpr int constant_non_42(int n) { // OK if (n == 42) { static int value = n; return value; } return n; } constexpr int uninit() { struct { int a; } s; return s.a; // error: uninitialized read of \tcode{s.a} } constexpr int prev(int x) { return --x; } // OK constexpr int g(int x, int n) { // OK int r = 1; while (--n > 0) r *= x; return r; } \end{codeblock} \end{example} \pnum An invocation of a constexpr function in a given context produces the same result as an invocation of an equivalent non-constexpr function in the same context in all respects except that \begin{itemize} \item an invocation of a constexpr function can appear in a constant expression\iref{expr.const} and \item copy elision is not performed in a constant expression\iref{class.copy.elision}. \end{itemize} \begin{note} Declaring a function constexpr can change whether an expression is a constant expression. This can indirectly cause calls to \tcode{std::is_constant_evaluated} within an invocation of the function to produce a different value. \end{note} \begin{note} It is possible to write a constexpr function for which no invocation satisfies the requirements of a core constant expression. \end{note} \pnum The \keyword{constexpr} and \keyword{consteval} specifiers have no effect on the type of a constexpr function. \begin{example} \begin{codeblock} constexpr int bar(int x, int y) // OK { return x + y + x*y; } // ... int bar(int x, int y) // error: redefinition of \tcode{bar} { return x * 2 + 3 * y; } \end{codeblock} \end{example} \pnum A \keyword{constexpr} specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized. In any \keyword{constexpr} variable declaration, the full-expression of the initialization shall be a constant expression\iref{expr.const}. A \keyword{constexpr} variable that is an object, as well as any temporary to which a \keyword{constexpr} reference is bound, shall have constant destruction. \begin{example} \begin{codeblock} struct pixel { int x, y; }; constexpr pixel ur = { 1294, 1024 }; // OK constexpr pixel origin; // error: initializer missing \end{codeblock} \end{example} \rSec2[dcl.constinit]{The \keyword{constinit} specifier} \indextext{specifier!\idxcode{constinit}} \pnum The \keyword{constinit} specifier shall be applied only to a declaration of a variable with static or thread storage duration. If the specifier is applied to any declaration of a variable, it shall be applied to the initializing declaration. No diagnostic is required if no \keyword{constinit} declaration is reachable at the point of the initializing declaration. \pnum If a variable declared with the \keyword{constinit} specifier has dynamic initialization\iref{basic.start.dynamic}, the program is ill-formed, even if the implementation would perform that initialization as a static initialization\iref{basic.start.static}. \begin{note} The \keyword{constinit} specifier ensures that the variable is initialized during static initialization. \end{note} \pnum \begin{example} \begin{codeblock} const char * g() { return "dynamic initialization"; } constexpr const char * f(bool p) { return p ? "constant initializer" : g(); } constinit const char * c = f(true); // OK constinit const char * d = f(false); // error \end{codeblock} \end{example} \rSec2[dcl.inline]{The \keyword{inline} specifier}% \indextext{specifier!\idxcode{inline}} \pnum The \keyword{inline} specifier shall be applied only to the declaration of a variable or function. \pnum \indextext{specifier!\idxcode{inline}}% \indextext{inline function}% A function declaration\iref{dcl.fct,class.mfct,class.friend} with an \keyword{inline} specifier declares an \defnadj{inline}{function}. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions specified in this subclause shall still be respected. \begin{note} The \keyword{inline} keyword has no effect on the linkage of a function. In certain cases, an inline function cannot use names with internal linkage; see~\ref{basic.link}. \end{note} \pnum A variable declaration with an \keyword{inline} specifier declares an \defnadj{inline}{variable}. \pnum The \keyword{inline} specifier shall not appear on a block scope declaration or on the declaration of a function parameter. If the \keyword{inline} specifier is used in a friend function declaration, that declaration shall be a definition or the function shall have previously been declared inline. \pnum If a definition of a function or variable is reachable at the point of its first declaration as inline, the program is ill-formed. If a function or variable with external or module linkage is declared inline in one definition domain, an inline declaration of it shall be reachable from the end of every definition domain in which it is declared; no diagnostic is required. \begin{note} A call to an inline function or a use of an inline variable can be encountered before its definition becomes reachable in a translation unit. \end{note} \pnum \begin{note} An inline function or variable with external or module linkage can be defined in multiple translation units\iref{basic.def.odr}, but is one entity with one address. A type or \keyword{static} variable defined in the body of such a function is therefore a single entity. \end{note} \pnum If an inline function or variable that is attached to a named module is declared in a definition domain, it shall be defined in that domain. \begin{note} A constexpr function\iref{dcl.constexpr} is implicitly inline. In the global module, a function defined within a class definition is implicitly inline\iref{class.mfct,class.friend}. \end{note} \rSec2[dcl.type]{Type specifiers}% \rSec3[dcl.type.general]{General}% \indextext{specifier!type|see{type specifier}} \pnum The type-specifiers are \indextext{type!\idxcode{const}}% \indextext{type!\idxcode{volatile}}% % \begin{bnf} \nontermdef{type-specifier}\br simple-type-specifier\br elaborated-type-specifier\br typename-specifier\br cv-qualifier \end{bnf} \begin{bnf} \nontermdef{type-specifier-seq}\br type-specifier \opt{attribute-specifier-seq}\br type-specifier type-specifier-seq \end{bnf} \begin{bnf} \nontermdef{defining-type-specifier}\br type-specifier\br class-specifier\br enum-specifier \end{bnf} \begin{bnf} \nontermdef{defining-type-specifier-seq}\br defining-type-specifier \opt{attribute-specifier-seq}\br defining-type-specifier defining-type-specifier-seq \end{bnf} The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{type-specifier-seq} or a \grammarterm{defining-type-specifier-seq} appertains to the type denoted by the preceding \grammarterm{type-specifier}{s} or \grammarterm{defining-type-specifier}{s}\iref{dcl.meaning}. The \grammarterm{attribute-specifier-seq} affects the type only for the declaration it appears in, not other declarations involving the same type. \pnum As a general rule, at most one \grammarterm{defining-type-specifier} is allowed in the complete \grammarterm{decl-specifier-seq} of a \grammarterm{declaration} or in a \grammarterm{defining-type-specifier-seq}, and at most one \grammarterm{type-specifier} is allowed in a \grammarterm{type-specifier-seq}. The only exceptions to this rule are the following: \begin{itemize} \item \keyword{const} can be combined with any type specifier except itself. \item \tcode{volatile} can be combined with any type specifier except itself. \item \tcode{signed} or \tcode{unsigned} can be combined with \tcode{char}, \tcode{long}, \tcode{short}, or \tcode{int}. \item \tcode{short} or \tcode{long} can be combined with \tcode{int}. \item \tcode{long} can be combined with \tcode{double}. \item \tcode{long} can be combined with \tcode{long}. \end{itemize} \pnum Except in a declaration of a constructor, destructor, or conversion function, at least one \grammarterm{defining-type-specifier} that is not a \grammarterm{cv-qualifier} shall appear in a complete \grammarterm{type-specifier-seq} or a complete \grammarterm{decl-specifier-seq}. \begin{footnote} There is no special provision for a \grammarterm{decl-specifier-seq} that lacks a \grammarterm{type-specifier} or that has a \grammarterm{type-specifier} that only specifies \grammarterm{cv-qualifier}{s}. The ``implicit int'' rule of C is no longer supported. \end{footnote} \pnum \begin{note} \grammarterm{enum-specifier}{s}, \grammarterm{class-specifier}{s}, and \grammarterm{typename-specifier}{s} are discussed in \ref{dcl.enum}, \ref{class}, and \ref{temp.res}, respectively. The remaining \grammarterm{type-specifier}{s} are discussed in the rest of \ref{dcl.type}. \end{note} \rSec3[dcl.type.cv]{The \fakegrammarterm{cv-qualifier}{s}}% \indextext{specifier!cv-qualifier}% \indextext{initialization!\idxcode{const}}% \indextext{type specifier!\idxcode{const}}% \indextext{type specifier!\idxcode{volatile}} \pnum There are two \grammarterm{cv-qualifier}{s}, \keyword{const} and \tcode{volatile}. Each \grammarterm{cv-qualifier} shall appear at most once in a \grammarterm{cv-qualifier-seq}. If a \grammarterm{cv-qualifier} appears in a \grammarterm{decl-specifier-seq}, the \grammarterm{init-declarator-list} or \grammarterm{member-declarator-list} of the declaration shall not be empty. \begin{note} \ref{basic.type.qualifier} and \ref{dcl.fct} describe how cv-qualifiers affect object and function types. \end{note} Redundant cv-qualifications are ignored. \begin{note} For example, these could be introduced by typedefs. \end{note} \pnum \begin{note} Declaring a variable \keyword{const} can affect its linkage\iref{dcl.stc} and its usability in constant expressions\iref{expr.const}. As described in~\ref{dcl.init}, the definition of an object or subobject of const-qualified type must specify an initializer or be subject to default-initialization. \end{note} \pnum A pointer or reference to a cv-qualified type need not actually point or refer to a cv-qualified object, but it is treated as if it does; a const-qualified access path cannot be used to modify an object even if the object referenced is a non-const object and can be modified through some other access path. \begin{note} Cv-qualifiers are supported by the type system so that they cannot be subverted without casting\iref{expr.const.cast}. \end{note} \pnum \indextext{const object!undefined change to}% Any attempt to modify\iref{expr.ass,expr.post.incr,expr.pre.incr} a const object\iref{basic.type.qualifier} during its lifetime\iref{basic.life} results in undefined behavior. \begin{example} \begin{codeblock} const int ci = 3; // cv-qualified (initialized as required) ci = 4; // error: attempt to modify \keyword{const} int i = 2; // not cv-qualified const int* cip; // pointer to \tcode{const int} cip = &i; // OK, cv-qualified access path to unqualified *cip = 4; // error: attempt to modify through ptr to \keyword{const} int* ip; ip = const_cast(cip); // cast needed to convert \tcode{const int*} to \tcode{int*} *ip = 4; // defined: \tcode{*ip} points to \tcode{i}, a non-const object const int* ciq = new const int (3); // initialized as required int* iq = const_cast(ciq); // cast required *iq = 4; // undefined behavior: modifies a const object \end{codeblock} For another example, \begin{codeblock} struct X { mutable int i; int j; }; struct Y { X x; Y(); }; const Y y; y.x.i++; // well-formed: \keyword{mutable} member can be modified y.x.j++; // error: const-qualified member modified Y* p = const_cast(&y); // cast away const-ness of \tcode{y} p->x.i = 99; // well-formed: \keyword{mutable} member can be modified p->x.j = 99; // undefined behavior: modifies a const subobject \end{codeblock} \end{example} \pnum The semantics of an access through a volatile glvalue are \impldef{semantics of an access through a volatile glvalue}. If an attempt is made to access an object defined with a volatile-qualified type through the use of a non-volatile glvalue, the behavior is undefined. \pnum \indextext{type specifier!\idxcode{volatile}}% \indextext{\idxcode{volatile}!implementation-defined}% \begin{note} \tcode{volatile} is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. Furthermore, for some implementations, \tcode{volatile} might indicate that special hardware instructions are required to access the object. See~\ref{intro.execution} for detailed semantics. In general, the semantics of \tcode{volatile} are intended to be the same in \Cpp{} as they are in C. \end{note} \rSec3[dcl.type.simple]{Simple type specifiers}% \indextext{type specifier!simple} \pnum The simple type specifiers are \begin{bnf} \nontermdef{simple-type-specifier}\br \opt{nested-name-specifier} type-name\br nested-name-specifier \keyword{template} simple-template-id\br decltype-specifier\br placeholder-type-specifier\br \opt{nested-name-specifier} template-name\br \keyword{char}\br \keyword{char8_t}\br \keyword{char16_t}\br \keyword{char32_t}\br \keyword{wchar_t}\br \keyword{bool}\br \keyword{short}\br \keyword{int}\br \keyword{long}\br \keyword{signed}\br \keyword{unsigned}\br \keyword{float}\br \keyword{double}\br \keyword{void} \end{bnf} \begin{bnf} \nontermdef{type-name}\br class-name\br enum-name\br typedef-name \end{bnf} \pnum \indextext{component name} The component names of a \grammarterm{simple-type-specifier} are those of its \grammarterm{nested-name-specifier}, \grammarterm{type-name}, \grammarterm{simple-template-id}, \grammarterm{template-name}, and/or \grammarterm{type-constraint} (if it is a \grammarterm{placeholder-type-specifier}). The component name of a \grammarterm{type-name} is the first name in it. \pnum \indextext{type specifier!\idxcode{char}}% \indextext{type specifier!\idxcode{char8_t}}% \indextext{type specifier!\idxcode{char16_t}}% \indextext{type specifier!\idxcode{char32_t}}% \indextext{type specifier!\idxcode{wchar_t}}% \indextext{type specifier!\idxcode{bool}}% \indextext{type specifier!\idxcode{short}}% \indextext{type specifier!\idxcode{int}}% \indextext{type specifier!\idxcode{long}}% \indextext{type specifier!\idxcode{signed}}% \indextext{type specifier!\idxcode{unsigned}}% \indextext{type specifier!\idxcode{float}}% \indextext{type specifier!\idxcode{double}}% \indextext{type specifier!\idxcode{void}}% \indextext{\idxgram{type-name}}% \indextext{\idxgram{lambda-introducer}}% A \grammarterm{placeholder-type-specifier} is a placeholder for a type to be deduced\iref{dcl.spec.auto}. \indextext{deduction!class template arguments}% A \grammarterm{type-specifier} of the form \opt{\keyword{typename}} \opt{\grammarterm{nested-name-specifier}} \grammarterm{template-name} is a placeholder for a deduced class type\iref{dcl.type.class.deduct}. The \grammarterm{nested-name-specifier}, if any, shall be non-dependent and the \grammarterm{template-name} shall name a deducible template. A \defnadj{deducible}{template} is either a class template or is an alias template whose \grammarterm{defining-type-id} is of the form \begin{ncsimplebnf} \opt{\keyword{typename}} \opt{nested-name-specifier} \opt{\keyword{template}} simple-template-id \end{ncsimplebnf} where the \grammarterm{nested-name-specifier} (if any) is non-dependent and the \grammarterm{template-name} of the \grammarterm{simple-template-id} names a deducible template. \begin{note} An injected-class-name is never interpreted as a \grammarterm{template-name} in contexts where class template argument deduction would be performed\iref{temp.local}. \end{note} The other \grammarterm{simple-type-specifier}{s} specify either a previously-declared type, a type determined from an expression, or one of the fundamental types\iref{basic.fundamental}. \tref{dcl.type.simple} summarizes the valid combinations of \grammarterm{simple-type-specifier}{s} and the types they specify. \begin{simpletypetable} {\grammarterm{simple-type-specifier}{s} and the types they specify} {dcl.type.simple} {ll} \topline \hdstyle{Specifier(s)} & \hdstyle{Type} \\ \capsep \grammarterm{type-name} & the type named \\ \grammarterm{simple-template-id} & the type as defined in~\ref{temp.names}\\ \grammarterm{decltype-specifier} & the type as defined in~\ref{dcl.type.decltype}\\ \grammarterm{placeholder-type-specifier} & the type as defined in~\ref{dcl.spec.auto}\\ \grammarterm{template-name} & the type as defined in~\ref{dcl.type.class.deduct}\\ \tcode{char} & ``\tcode{char}'' \\ \tcode{unsigned char} & ``\tcode{unsigned char}'' \\ \tcode{signed char} & ``\tcode{signed char}'' \\ \keyword{char8_t} & ``\tcode{char8_t}'' \\ \keyword{char16_t} & ``\tcode{char16_t}'' \\ \keyword{char32_t} & ``\tcode{char32_t}'' \\ \tcode{bool} & ``\tcode{bool}'' \\ \tcode{unsigned} & ``\tcode{unsigned int}'' \\ \tcode{unsigned int} & ``\tcode{unsigned int}'' \\ \tcode{signed} & ``\tcode{int}'' \\ \tcode{signed int} & ``\tcode{int}'' \\ \tcode{int} & ``\tcode{int}'' \\ \tcode{unsigned short int} & ``\tcode{unsigned short int}'' \\ \tcode{unsigned short} & ``\tcode{unsigned short int}'' \\ \tcode{unsigned long int} & ``\tcode{unsigned long int}'' \\ \tcode{unsigned long} & ``\tcode{unsigned long int}'' \\ \tcode{unsigned long long int} & ``\tcode{unsigned long long int}''\\ \tcode{unsigned long long} & ``\tcode{unsigned long long int}''\\ \tcode{signed long int} & ``\tcode{long int}'' \\ \tcode{signed long} & ``\tcode{long int}'' \\ \tcode{signed long long int} & ``\tcode{long long int}'' \\ \tcode{signed long long} & ``\tcode{long long int}'' \\ \tcode{long long int} & ``\tcode{long long int}'' \\ \tcode{long long} & ``\tcode{long long int}'' \\ \tcode{long int} & ``\tcode{long int}'' \\ \tcode{long} & ``\tcode{long int}'' \\ \tcode{signed short int} & ``\tcode{short int}'' \\ \tcode{signed short} & ``\tcode{short int}'' \\ \tcode{short int} & ``\tcode{short int}'' \\ \tcode{short} & ``\tcode{short int}'' \\ \keyword{wchar_t} & ``\tcode{wchar_t}'' \\ \tcode{float} & ``\tcode{float}'' \\ \tcode{double} & ``\tcode{double}'' \\ \tcode{long double} & ``\tcode{long double}'' \\ \keyword{void} & ``\tcode{void}'' \\ \end{simpletypetable} \pnum When multiple \grammarterm{simple-type-specifier}{s} are allowed, they can be freely intermixed with other \grammarterm{decl-specifier}{s} in any order. \begin{note} It is \impldef{signedness of \tcode{char}} whether objects of \tcode{char} type are represented as signed or unsigned quantities. The \tcode{signed} specifier forces \tcode{char} objects to be signed; it is redundant in other contexts. \end{note} \rSec3[dcl.type.elab]{Elaborated type specifiers}% \indextext{type specifier!elaborated}% \indextext{\idxcode{typename}}% \indextext{type specifier!\idxcode{enum}} \begin{bnf} \nontermdef{elaborated-type-specifier}\br class-key \opt{attribute-specifier-seq} \opt{nested-name-specifier} identifier\br class-key simple-template-id\br class-key nested-name-specifier \opt{\keyword{template}} simple-template-id\br \keyword{enum} \opt{nested-name-specifier} identifier \end{bnf} \pnum \indextext{component name}% The component names of an \grammarterm{elaborated-type-specifier} are its \grammarterm{identifier} (if any) and those of its \grammarterm{nested-name-specifier} and \grammarterm{simple-template-id} (if any). \pnum \indextext{class name!elaborated}% \indextext{name!elaborated!\idxcode{enum}}% If an \grammarterm{elaborated-type-specifier} is the sole constituent of a declaration, the declaration is ill-formed unless it is an explicit specialization\iref{temp.expl.spec}, an explicit instantiation\iref{temp.explicit} or it has one of the following forms: \begin{ncsimplebnf} class-key \opt{attribute-specifier-seq} identifier \terminal{;}\br class-key \opt{attribute-specifier-seq} simple-template-id \terminal{;} \end{ncsimplebnf} In the first case, the \grammarterm{elaborated-type-specifier} declares the \grammarterm{identifier} as a \grammarterm{class-name}. The second case shall appear only in an \grammarterm{explicit-specialization}\iref{temp.expl.spec} or in a \grammarterm{template-declaration} (where it declares a partial specialization\iref{temp.decls}). The \grammarterm{attribute-specifier-seq}, if any, appertains to the class or template being declared. \pnum Otherwise, an \grammarterm{elaborated-type-specifier} $E$ shall not have an \grammarterm{attribute-specifier-seq}. If $E$ contains an \grammarterm{identifier} but no \grammarterm{nested-name-specifier} and (unqualified) lookup for the \grammarterm{identifier} finds nothing, $E$ shall not be introduced by the \keyword{enum} keyword and declares the \grammarterm{identifier} as a \grammarterm{class-name}. The target scope of $E$ is the nearest enclosing namespace or block scope. \pnum If an \grammarterm{elaborated-type-specifier} appears with the \keyword{friend} specifier as an entire \grammarterm{member-declaration}, the \grammarterm{member-declaration} shall have one of the following forms: \begin{ncsimplebnf} \keyword{friend} class-key \opt{nested-name-specifier} identifier \terminal{;}\br \keyword{friend} class-key simple-template-id \terminal{;}\br \keyword{friend} class-key nested-name-specifier \opt{\keyword{template}} simple-template-id \terminal{;} \end{ncsimplebnf} Any unqualified lookup for the \grammarterm{identifier} (in the first case) does not consider scopes that contain the target scope; no name is bound. \begin{note} A \grammarterm{using-directive} in the target scope is ignored if it refers to a namespace not contained by that scope. \ref{basic.lookup.elab} describes how name lookup proceeds in an \grammarterm{elaborated-type-specifier}. \end{note} \pnum \begin{note} An \grammarterm{elaborated-type-specifier} can be used to refer to a previously declared \grammarterm{class-name} or \grammarterm{enum-name} even if the name has been hidden by a non-type declaration. \end{note} If the \grammarterm{identifier} or \grammarterm{simple-template-id} resolves to a \grammarterm{class-name} or \grammarterm{enum-name}, the \grammarterm{elaborated-type-specifier} introduces it into the declaration the same way a \grammarterm{simple-type-specifier} introduces its \grammarterm{type-name}\iref{dcl.type.simple}. If the \grammarterm{identifier} or \grammarterm{simple-template-id} resolves to a \grammarterm{typedef-name}\iref{dcl.typedef,temp.names}, the \grammarterm{elaborated-type-specifier} is ill-formed. \begin{note} This implies that, within a class template with a template \grammarterm{type-parameter} \tcode{T}, the declaration \begin{codeblock} friend class T; \end{codeblock} is ill-formed. However, the similar declaration \tcode{friend T;} is allowed\iref{class.friend}. \end{note} \pnum The \grammarterm{class-key} or \keyword{enum} keyword present in the \grammarterm{elaborated-type-specifier} shall agree in kind with the declaration to which the name in the \grammarterm{elaborated-type-specifier} refers. This rule also applies to the form of \grammarterm{elaborated-type-specifier} that declares a \grammarterm{class-name} or friend class since it can be construed as referring to the definition of the class. Thus, in any \grammarterm{elaborated-type-specifier}, the \keyword{enum} keyword shall be used to refer to an enumeration\iref{dcl.enum}, the \keyword{union} \grammarterm{class-key} shall be used to refer to a union\iref{class.union}, and either the \keyword{class} or \keyword{struct} \grammarterm{class-key} shall be used to refer to a non-union class\iref{class.pre}. \begin{example} \begin{codeblock} enum class E { a, b }; enum E x = E::a; // OK struct S { } s; class S* p = &s; // OK \end{codeblock} \end{example} \rSec3[dcl.type.decltype]{Decltype specifiers}% \indextext{type specifier!\idxcode{decltype}}% \begin{bnf} \nontermdef{decltype-specifier}\br \keyword{decltype} \terminal{(} expression \terminal{)} \end{bnf} \pnum \indextext{type specifier!\idxcode{decltype}}% For an expression $E$, the type denoted by \tcode{decltype($E$)} is defined as follows: \begin{itemize} \item if $E$ is an unparenthesized \grammarterm{id-expression} naming a structured binding\iref{dcl.struct.bind}, \tcode{decltype($E$)} is the referenced type as given in the specification of the structured binding declaration; \item otherwise, if $E$ is an unparenthesized \grammarterm{id-expression} naming a non-type \grammarterm{template-parameter}\iref{temp.param}, \tcode{decltype($E$)} is the type of the \grammarterm{template-parameter} after performing any necessary type deduction\iref{dcl.spec.auto,dcl.type.class.deduct}; \item otherwise, if $E$ is an unparenthesized \grammarterm{id-expression} or an unparenthesized class member access\iref{expr.ref}, \tcode{decltype($E$)} is the type of the entity named by $E$. If there is no such entity, the program is ill-formed; \item otherwise, if $E$ is an xvalue, \tcode{decltype($E$)} is \tcode{T\&\&}, where \tcode{T} is the type of $E$; \item otherwise, if $E$ is an lvalue, \tcode{decltype($E$)} is \tcode{T\&}, where \tcode{T} is the type of $E$; \item otherwise, \tcode{decltype($E$)} is the type of $E$. \end{itemize} The operand of the \keyword{decltype} specifier is an unevaluated operand\iref{term.unevaluated.operand}. \begin{example} \begin{codeblock} const int&& foo(); int i; struct A { double x; }; const A* a = new A(); decltype(foo()) x1 = 17; // type is \tcode{const int\&\&} decltype(i) x2; // type is \tcode{int} decltype(a->x) x3; // type is \tcode{double} decltype((a->x)) x4 = x3; // type is \tcode{const double\&} \end{codeblock} \end{example} \begin{note} The rules for determining types involving \tcode{decltype(auto)} are specified in~\ref{dcl.spec.auto}. \end{note} \pnum If the operand of a \grammarterm{decltype-specifier} is a prvalue and is not a (possibly parenthesized) immediate invocation\iref{expr.const}, the temporary materialization conversion is not applied\iref{conv.rval} and no result object is provided for the prvalue. The type of the prvalue may be incomplete or an abstract class type. \begin{note} As a result, storage is not allocated for the prvalue and it is not destroyed. Thus, a class type is not instantiated as a result of being the type of a function call in this context. In this context, the common purpose of writing the expression is merely to refer to its type. In that sense, a \grammarterm{decltype-specifier} is analogous to a use of a \grammarterm{typedef-name}, so the usual reasons for requiring a complete type do not apply. In particular, it is not necessary to allocate storage for a temporary object or to enforce the semantic constraints associated with invoking the type's destructor. \end{note} \begin{note} Unlike the preceding rule, parentheses have no special meaning in this context. \end{note} \begin{example} \begin{codeblock} template struct A { ~A() = delete; }; template auto h() -> A; template auto i(T) // identity -> T; template auto f(T) // \#1 -> decltype(i(h())); // forces completion of \tcode{A} and implicitly uses \tcode{A::\~{}A()} // for the temporary introduced by the use of \tcode{h()}. // (A temporary is not introduced as a result of the use of \tcode{i()}.) template auto f(T) // \#2 -> void; auto g() -> void { f(42); // OK, calls \#2. (\#1 is not a viable candidate: type deduction // fails\iref{temp.deduct} because \tcode{A::\~{}A()} is implicitly used in its // \grammarterm{decltype-specifier}) } template auto q(T) -> decltype((h())); // does not force completion of \tcode{A}; \tcode{A::\~{}A()} is not implicitly // used within the context of this \grammarterm{decltype-specifier} void r() { q(42); // error: deduction against \tcode{q} succeeds, so overload resolution selects // the specialization ``\tcode{q(T) -> decltype((h()))}'' with \tcode{T}$=$\tcode{int}; // the return type is \tcode{A}, so a temporary is introduced and its // destructor is used, so the program is ill-formed } \end{codeblock} \end{example} \rSec3[dcl.spec.auto]{Placeholder type specifiers}% \rSec4[dcl.spec.auto.general]{General}% \indextext{type specifier!\idxcode{auto}} \indextext{type specifier!\idxcode{decltype(auto)}}% \begin{bnf} \nontermdef{placeholder-type-specifier}\br \opt{type-constraint} \keyword{auto}\br \opt{type-constraint} \keyword{decltype} \terminal{(} \keyword{auto} \terminal{)} \end{bnf} \pnum A \grammarterm{placeholder-type-specifier} designates a placeholder type that will be replaced later by deduction from an initializer. \pnum A \grammarterm{placeholder-type-specifier} of the form \opt{\grammarterm{type-constraint}} \keyword{auto} can be used as a \grammarterm{decl-specifier} of the \grammarterm{decl-specifier-seq} of a \grammarterm{parameter-declaration} of a function declaration or \grammarterm{lambda-expression} and, if it is not the \keyword{auto} \grammarterm{type-specifier} introducing a \grammarterm{trailing-return-type} (see below), is a \defn{generic parameter type placeholder} of the function declaration or \grammarterm{lambda-expression}. \begin{note} Having a generic parameter type placeholder signifies that the function is an abbreviated function template\iref{dcl.fct} or the lambda is a generic lambda\iref{expr.prim.lambda}. \end{note} \pnum A placeholder type can appear with a function declarator in the \grammarterm{decl-specifier-seq}, \grammarterm{type-specifier-seq}, \grammarterm{conversion-function-id}, or \grammarterm{trailing-return-type}, in any context where such a declarator is valid. If the function declarator includes a \grammarterm{trailing-return-type}\iref{dcl.fct}, that \grammarterm{trailing-return-type} specifies the declared return type of the function. Otherwise, the function declarator shall declare a function. If the declared return type of the function contains a placeholder type, the return type of the function is deduced from non-discarded \tcode{return} statements, if any, in the body of the function\iref{stmt.if}. \pnum The type of a variable declared using a placeholder type is deduced from its initializer. This use is allowed in an initializing declaration\iref{dcl.init} of a variable. The placeholder type shall appear as one of the \grammarterm{decl-specifier}{s} in the \grammarterm{decl-specifier-seq} and the \grammarterm{decl-specifier-seq} shall be followed by one or more \grammarterm{declarator}{s}, each of which shall be followed by a non-empty \grammarterm{initializer}. \begin{example} \begin{codeblock} auto x = 5; // OK, \tcode{x} has type \tcode{int} const auto *v = &x, u = 6; // OK, \tcode{v} has type \tcode{const int*}, \tcode{u} has type \tcode{const int} static auto y = 0.0; // OK, \tcode{y} has type \tcode{double} auto int r; // error: \keyword{auto} is not a \grammarterm{storage-class-specifier} auto f() -> int; // OK, \tcode{f} returns \tcode{int} auto g() { return 0.0; } // OK, \tcode{g} returns \tcode{double} auto h(); // OK, \tcode{h}'s return type will be deduced when it is defined \end{codeblock} \end{example} The \keyword{auto} \grammarterm{type-specifier} can also be used to introduce a structured binding declaration\iref{dcl.struct.bind}. \pnum A placeholder type can also be used in the \grammarterm{type-specifier-seq} in the \grammarterm{new-type-id} or \grammarterm{type-id} of a \grammarterm{new-expression}\iref{expr.new} and as a \grammarterm{decl-specifier} of the \grammarterm{parameter-declaration}{'s} \grammarterm{decl-specifier-seq} in a \grammarterm{template-parameter}\iref{temp.param}. The \tcode{auto} \grammarterm{type-specifier} can also be used as the \grammarterm{simple-type-specifier} in an explicit type conversion (functional notation)\iref{expr.type.conv}. \pnum A program that uses a placeholder type in a context not explicitly allowed in \ref{dcl.spec.auto} is ill-formed. \pnum If the \grammarterm{init-declarator-list} contains more than one \grammarterm{init-declarator}, they shall all form declarations of variables. The type of each declared variable is determined by placeholder type deduction\iref{dcl.type.auto.deduct}, and if the type that replaces the placeholder type is not the same in each deduction, the program is ill-formed. \begin{example} \begin{codeblock} auto x = 5, *y = &x; // OK, \keyword{auto} is \tcode{int} auto a = 5, b = { 1, 2 }; // error: different types for \keyword{auto} \end{codeblock} \end{example} \pnum If a function with a declared return type that contains a placeholder type has multiple non-discarded \tcode{return} statements, the return type is deduced for each such \tcode{return} statement. If the type deduced is not the same in each deduction, the program is ill-formed. \pnum If a function with a declared return type that uses a placeholder type has no non-discarded \tcode{return} statements, the return type is deduced as though from a \tcode{return} statement with no operand at the closing brace of the function body. \begin{example} \begin{codeblock} auto f() { } // OK, return type is \keyword{void} auto* g() { } // error: cannot deduce \tcode{auto*} from \tcode{void()} \end{codeblock} \end{example} \pnum An exported function with a declared return type that uses a placeholder type shall be defined in the translation unit containing its exported declaration, outside the \grammarterm{private-module-fragment} (if any). \begin{note} The deduced return type cannot have a name with internal linkage\iref{basic.link}. \end{note} \pnum If a variable or function with an undeduced placeholder type is named by an expression\iref{basic.def.odr}, the program is ill-formed. Once a non-discarded \tcode{return} statement has been seen in a function, however, the return type deduced from that statement can be used in the rest of the function, including in other \tcode{return} statements. \begin{example} \begin{codeblock} auto n = n; // error: \tcode{n}'s initializer refers to \tcode{n} auto f(); void g() { &f; } // error: \tcode{f}'s return type is unknown auto sum(int i) { if (i == 1) return i; // \tcode{sum}'s return type is \tcode{int} else return sum(i-1)+i; // OK, \tcode{sum}'s return type has been deduced } \end{codeblock} \end{example} \pnum Return type deduction for a templated function with a placeholder in its declared type occurs when the definition is instantiated even if the function body contains a \tcode{return} statement with a non-type-dependent operand. \begin{note} Therefore, any use of a specialization of the function template will cause an implicit instantiation. Any errors that arise from this instantiation are not in the immediate context of the function type and can result in the program being ill-formed\iref{temp.deduct}. \end{note} \begin{example} \begin{codeblock} template auto f(T t) { return t; } // return type deduced at instantiation time typedef decltype(f(1)) fint_t; // instantiates \tcode{f} to deduce return type template auto f(T* t) { return *t; } void g() { int (*p)(int*) = &f; } // instantiates both \tcode{f}s to determine return types, // chooses second \end{codeblock} \end{example} \pnum If a function or function template $F$ has a declared return type that uses a placeholder type, redeclarations or specializations of $F$ shall use that placeholder type, not a deduced type; otherwise, they shall not use a placeholder type. \begin{example} \begin{codeblock} auto f(); auto f() { return 42; } // return type is \tcode{int} auto f(); // OK int f(); // error: \keyword{auto} and \tcode{int} don't match decltype(auto) f(); // error: \keyword{auto} and \tcode{decltype(auto)} don't match template auto g(T t) { return t; } // \#1 template auto g(int); // OK, return type is \tcode{int} template char g(char); // error: no matching template template<> auto g(double); // OK, forward declaration with unknown return type template T g(T t) { return t; } // OK, not functionally equivalent to \#1 template char g(char); // OK, now there is a matching template template auto g(float); // still matches \#1 void h() { return g(42); } // error: ambiguous template struct A { friend T frf(T); }; auto frf(int i) { return i; } // not a friend of \tcode{A} extern int v; auto v = 17; // OK, redeclares \tcode{v} struct S { static int i; }; auto S::i = 23; // OK \end{codeblock} \end{example} \pnum A function declared with a return type that uses a placeholder type shall not be \keyword{virtual}\iref{class.virtual}. \pnum A function declared with a return type that uses a placeholder type shall not be a coroutine\iref{dcl.fct.def.coroutine}. \pnum An explicit instantiation declaration\iref{temp.explicit} does not cause the instantiation of an entity declared using a placeholder type, but it also does not prevent that entity from being instantiated as needed to determine its type. \begin{example} \begin{codeblock} template auto f(T t) { return t; } extern template auto f(int); // does not instantiate \tcode{f} int (*p)(int) = f; // instantiates \tcode{f} to determine its return type, but an explicit // instantiation definition is still required somewhere in the program \end{codeblock} \end{example} \rSec4[dcl.type.auto.deduct]{Placeholder type deduction} \indextext{deduction!placeholder type}% \pnum \defnx{Placeholder type deduction}{placeholder type deduction} is the process by which a type containing a placeholder type is replaced by a deduced type. \pnum A type \tcode{T} containing a placeholder type, and a corresponding \grammarterm{initializer-clause} $E$, are determined as follows: \begin{itemize} \item For a non-discarded \tcode{return} statement that occurs in a function declared with a return type that contains a placeholder type, \tcode{T} is the declared return type. \begin{itemize} \item If the \tcode{return} statement has no operand, then $E$ is \tcode{void()}. \item If the operand is a \grammarterm{braced-init-list}\iref{dcl.init.list}, the program is ill-formed. \item If the operand is an \grammarterm{expression} $X$ that is not an \grammarterm{assignment-expression}, $E$ is \tcode{($X$)}. \begin{note} A comma expression\iref{expr.comma} is not an \grammarterm{assignment-expression}. \end{note} \item Otherwise, $E$ is the operand of the \tcode{return} statement. \end{itemize} If $E$ has type \keyword{void}, \tcode{T} shall be either \opt{\grammarterm{type-constraint}} \tcode{decltype(auto)} or \cv{}~\opt{\grammarterm{type-constraint}} \keyword{auto}. \item For a variable declared with a type that contains a placeholder type, \tcode{T} is the declared type of the variable. \begin{itemize} \item If the initializer of the variable is a \grammarterm{brace-or-equal-initializer} of the form \tcode{= \grammarterm{initializer-clause}}, $E$ is the \grammarterm{initializer-clause}. \item If the initializer is a \grammarterm{braced-init-list}, it shall consist of a single brace-enclosed \grammarterm{assignment-expression} and $E$ is the \grammarterm{assignment-expression}. \item If the initializer is a parenthesized \grammarterm{expression-list}, the \grammarterm{expression-list} shall be a single \grammarterm{assignment-expression} and $E$ is the \grammarterm{assignment-expression}. \end{itemize} \item For an explicit type conversion\iref{expr.type.conv}, \tcode{T} is the specified type, which shall be \keyword{auto}. \begin{itemize} \item If the initializer is a \grammarterm{braced-init-list}, it shall consist of a single brace-enclosed \grammarterm{assignment-expression} and $E$ is the \grammarterm{assignment-expression}. \item If the initializer is a parenthesized \grammarterm{expression-list}, the \grammarterm{expression-list} shall be a single \grammarterm{assignment-expression} and $E$ is the \grammarterm{assignment-expression}. \end{itemize} \item For a non-type template parameter declared with a type that contains a placeholder type, \tcode{T} is the declared type of the non-type template parameter and $E$ is the corresponding template argument. \end{itemize} \tcode{T} shall not be an array type. \pnum If the \grammarterm{placeholder-type-specifier} is of the form \opt{\grammarterm{type-constraint}} \keyword{auto}, the deduced type $\mathtt{T}'$ replacing \tcode{T} is determined using the rules for template argument deduction. If the initialization is copy-list-initialization, a declaration of \tcode{std::initializer_list} shall precede\iref{basic.lookup.general} the \grammarterm{placeholder-type-specifier}. Obtain \tcode{P} from \tcode{T} by replacing the occurrences of \opt{\grammarterm{type-constraint}} \keyword{auto} either with a new invented type template parameter \tcode{U} or, if the initialization is copy-list-initialization, with \tcode{std::initializer_list}. Deduce a value for \tcode{U} using the rules of template argument deduction from a function call\iref{temp.deduct.call}, where \tcode{P} is a function template parameter type and the corresponding argument is $E$. If the deduction fails, the declaration is ill-formed. Otherwise, $\mathtt{T}'$ is obtained by substituting the deduced \tcode{U} into \tcode{P}. \begin{example} \begin{codeblock} auto x1 = { 1, 2 }; // \tcode{decltype(x1)} is \tcode{std::initializer_list} auto x2 = { 1, 2.0 }; // error: cannot deduce element type auto x3{ 1, 2 }; // error: not a single element auto x4 = { 3 }; // \tcode{decltype(x4)} is \tcode{std::initializer_list} auto x5{ 3 }; // \tcode{decltype(x5)} is \tcode{int} \end{codeblock} \end{example} \begin{example} \begin{codeblock} const auto &i = expr; \end{codeblock} The type of \tcode{i} is the deduced type of the parameter \tcode{u} in the call \tcode{f(expr)} of the following invented function template: \begin{codeblock} template void f(const U& u); \end{codeblock} \end{example} \pnum If the \grammarterm{placeholder-type-specifier} is of the form \opt{\grammarterm{type-constraint}} \tcode{decltype(auto)}, \tcode{T} shall be the placeholder alone. The type deduced for \tcode{T} is determined as described in~\ref{dcl.type.decltype}, as though $E$ had been the operand of the \keyword{decltype}. \begin{example} \begin{codeblock} int i; int&& f(); auto x2a(i); // \tcode{decltype(x2a)} is \tcode{int} decltype(auto) x2d(i); // \tcode{decltype(x2d)} is \tcode{int} auto x3a = i; // \tcode{decltype(x3a)} is \tcode{int} decltype(auto) x3d = i; // \tcode{decltype(x3d)} is \tcode{int} auto x4a = (i); // \tcode{decltype(x4a)} is \tcode{int} decltype(auto) x4d = (i); // \tcode{decltype(x4d)} is \tcode{int\&} auto x5a = f(); // \tcode{decltype(x5a)} is \tcode{int} decltype(auto) x5d = f(); // \tcode{decltype(x5d)} is \tcode{int\&\&} auto x6a = { 1, 2 }; // \tcode{decltype(x6a)} is \tcode{std::initializer_list} decltype(auto) x6d = { 1, 2 }; // error: \tcode{\{ 1, 2 \}} is not an expression auto *x7a = &i; // \tcode{decltype(x7a)} is \tcode{int*} decltype(auto)*x7d = &i; // error: declared type is not plain \tcode{decltype(auto)} auto f1(int x) -> decltype((x)) { return (x); } // return type is \tcode{int\&} auto f2(int x) -> decltype(auto) { return (x); } // return type is \tcode{int\&\&} \end{codeblock} \end{example} \pnum For a \grammarterm{placeholder-type-specifier} with a \grammarterm{type-constraint}, the immediately-declared constraint\iref{temp.param} of the \grammarterm{type-constraint} for the type deduced for the placeholder shall be satisfied. \rSec3[dcl.type.class.deduct]{Deduced class template specialization types} \indextext{deduction!class template arguments}% \pnum If a placeholder for a deduced class type appears as a \grammarterm{decl-specifier} in the \grammarterm{decl-specifier-seq} of an initializing declaration\iref{dcl.init} of a variable, the declared type of the variable shall be \cv{}~\tcode{T}, where \tcode{T} is the placeholder. \begin{example} \begin{codeblock} template struct A { A(T...) {} }; A x[29]{}; // error: no declarator operators allowed const A& y{}; // error: no declarator operators allowed \end{codeblock} \end{example} The placeholder is replaced by the return type of the function selected by overload resolution for class template deduction\iref{over.match.class.deduct}. If the \grammarterm{decl-specifier-seq} is followed by an \grammarterm{init-declarator-list} or \grammarterm{member-declarator-list} containing more than one \grammarterm{declarator}, the type that replaces the placeholder shall be the same in each deduction. \pnum A placeholder for a deduced class type can also be used in the \grammarterm{type-specifier-seq} in the \grammarterm{new-type-id} or \grammarterm{type-id} of a \grammarterm{new-expression}\iref{expr.new}, as the \grammarterm{simple-type-specifier} in an explicit type conversion (functional notation)\iref{expr.type.conv}, or as the \grammarterm{type-specifier} in the \grammarterm{parameter-declaration} of a \grammarterm{template-parameter}\iref{temp.param}. A placeholder for a deduced class type shall not appear in any other context. \pnum \begin{example} \begin{codeblock} template struct container { container(T t) {} template container(Iter beg, Iter end); }; template container(Iter b, Iter e) -> container::value_type>; std::vector v = { @\commentellip@ }; container c(7); // OK, deduces \tcode{int} for \tcode{T} auto d = container(v.begin(), v.end()); // OK, deduces \tcode{double} for \tcode{T} container e{5, 6}; // error: \tcode{int} is not an iterator \end{codeblock} \end{example} \indextext{specifier|)}% \rSec1[dcl.decl]{Declarators}% \rSec2[dcl.decl.general]{General}% \indextext{declarator|(} \indextext{initialization!class object|seealso{constructor}}% \indextext{\idxcode{*}|see{declarator, pointer}} \indextext{\idxcode{\&}|see{declarator, reference}}% \indextext{\idxcode{::*}|see{declarator, pointer-to-member}}% \indextext{\idxcode{[]}|see{declarator, array}}% \indextext{\idxcode{()}|see{declarator, function}}% \pnum A declarator declares a single variable, function, or type, within a declaration. The \grammarterm{init-declarator-list} appearing in a \grammarterm{simple-declaration} is a comma-separated sequence of declarators, each of which can have an initializer. \begin{bnf} \nontermdef{init-declarator-list}\br init-declarator\br init-declarator-list \terminal{,} init-declarator \end{bnf} \begin{bnf} \nontermdef{init-declarator}\br declarator \opt{initializer}\br declarator requires-clause \end{bnf} \pnum In all contexts, a \grammarterm{declarator} is interpreted as given below. Where an \grammarterm{abstract-declarator} can be used (or omitted) in place of a \grammarterm{declarator}\iref{dcl.fct,except.pre}, it is as if a unique identifier were included in the appropriate place\iref{dcl.name}. The preceding specifiers indicate the type, storage class 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 \tcode{*} (pointer to) and \tcode{()} (function returning). \begin{note} An \grammarterm{init-declarator} can also specify an initializer\iref{dcl.init}. \end{note} \pnum Each \grammarterm{init-declarator} or \grammarterm{member-declarator} in a declaration is analyzed separately as if it were in a declaration by itself. \begin{note} A declaration with several declarators is usually equivalent to the corresponding sequence of declarations each with a single declarator. That is, \begin{codeblock} T D1, D2, ... Dn; \end{codeblock} is usually equivalent to \begin{codeblock} T D1; T D2; ... T Dn; \end{codeblock} where \tcode{T} is a \grammarterm{decl-specifier-seq} and each \tcode{Di} is an \grammarterm{init-declarator} or \grammarterm{member-declarator}. One exception is when a name introduced by one of the \grammarterm{declarator}{s} hides a type name used by the \grammarterm{decl-specifier}{s}, so that when the same \grammarterm{decl-specifier}{s} are used in a subsequent declaration, they do not have the same meaning, as in \begin{codeblock} struct S { @\commentellip@ }; S S, T; // declare two instances of \tcode{struct S} \end{codeblock} which is not equivalent to \begin{codeblock} struct S { @\commentellip@ }; S S; S T; // error \end{codeblock} Another exception is when \tcode{T} is \keyword{auto}\iref{dcl.spec.auto}, for example: \begin{codeblock} auto i = 1, j = 2.0; // error: deduced types for \tcode{i} and \tcode{j} do not match \end{codeblock} as opposed to \begin{codeblock} auto i = 1; // OK, \tcode{i} deduced to have type \tcode{int} auto j = 2.0; // OK, \tcode{j} deduced to have type \tcode{double} \end{codeblock} \end{note} \pnum The optional \grammarterm{requires-clause} in an \grammarterm{init-declarator} or \grammarterm{member-declarator} shall be present only if the declarator declares a templated function\iref{temp.pre}. % \indextext{trailing requires-clause@trailing \gterm{requires-clause}|see{\gterm{requires-clause}, trailing}}% When present after a declarator, the \grammarterm{requires-clause} is called the \defnx{trailing \grammarterm{requires-clause}}{% \idxgram{requires-clause}!trailing}. The trailing \grammarterm{requires-clause} introduces the \grammarterm{constraint-expression} that results from interpreting its \grammarterm{constraint-logical-or-expression} as a \grammarterm{constraint-expression}. % \begin{example} \begin{codeblock} void f1(int a) requires true; // error: non-templated function template auto f2(T a) -> bool requires true; // OK template auto f3(T a) requires true -> bool; // error: \grammarterm{requires-clause} precedes \grammarterm{trailing-return-type} void (*pf)() requires true; // error: constraint on a variable void g(int (*)() requires true); // error: constraint on a \grammarterm{parameter-declaration} auto* p = new void(*)(char) requires true; // error: not a function declaration \end{codeblock} \end{example} \pnum Declarators have the syntax \begin{bnf} \nontermdef{declarator}\br ptr-declarator\br noptr-declarator parameters-and-qualifiers trailing-return-type \end{bnf} \begin{bnf} \nontermdef{ptr-declarator}\br noptr-declarator\br ptr-operator ptr-declarator \end{bnf} \begin{bnf} \nontermdef{noptr-declarator}\br declarator-id \opt{attribute-specifier-seq}\br noptr-declarator parameters-and-qualifiers\br noptr-declarator \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br \terminal{(} ptr-declarator \terminal{)} \end{bnf} \begin{bnf} \nontermdef{parameters-and-qualifiers}\br \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br \bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \end{bnf} \begin{bnf} \nontermdef{trailing-return-type}\br \terminal{->} type-id \end{bnf} \begin{bnf} \microtypesetup{protrusion=false}\obeyspaces \nontermdef{ptr-operator}\br \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq}\br \terminal{\&} \opt{attribute-specifier-seq}\br \terminal{\&\&} \opt{attribute-specifier-seq}\br nested-name-specifier \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \end{bnf} \begin{bnf} \nontermdef{cv-qualifier-seq}\br cv-qualifier \opt{cv-qualifier-seq} \end{bnf} \begin{bnf} \nontermdef{cv-qualifier}\br \keyword{const}\br \keyword{volatile} \end{bnf} \begin{bnf} \nontermdef{ref-qualifier}\br \terminal{\&}\br \terminal{\&\&} \end{bnf} \begin{bnf} \nontermdef{declarator-id}\br \opt{\terminal{...}} id-expression \end{bnf} \rSec2[dcl.name]{Type names} \pnum \indextext{type name}% To specify type conversions explicitly, \indextext{operator!cast}% and as an argument of \tcode{sizeof}, \tcode{alignof}, \keyword{new}, or \tcode{typeid}, the name of a type shall be specified. This can be done with a \grammarterm{type-id}, which is syntactically a declaration for a variable or function of that type that omits the name of the entity. \begin{bnf} \nontermdef{type-id}\br type-specifier-seq \opt{abstract-declarator} \end{bnf} \begin{bnf} \nontermdef{defining-type-id}\br defining-type-specifier-seq \opt{abstract-declarator} \end{bnf} \begin{bnf} \nontermdef{abstract-declarator}\br ptr-abstract-declarator\br \opt{noptr-abstract-declarator} parameters-and-qualifiers trailing-return-type\br abstract-pack-declarator \end{bnf} \begin{bnf} \nontermdef{ptr-abstract-declarator}\br noptr-abstract-declarator\br ptr-operator \opt{ptr-abstract-declarator} \end{bnf} \begin{bnf} \nontermdef{noptr-abstract-declarator}\br \opt{noptr-abstract-declarator} parameters-and-qualifiers\br \opt{noptr-abstract-declarator} \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br \terminal{(} ptr-abstract-declarator \terminal{)} \end{bnf} \begin{bnf} \nontermdef{abstract-pack-declarator}\br noptr-abstract-pack-declarator\br ptr-operator abstract-pack-declarator \end{bnf} \begin{bnf} \nontermdef{noptr-abstract-pack-declarator}\br noptr-abstract-pack-declarator parameters-and-qualifiers\br noptr-abstract-pack-declarator \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq}\br \terminal{...} \end{bnf} It is possible to identify uniquely the location in the \grammarterm{abstract-declarator} where the identifier would appear if the construction were a declarator in a declaration. The named type is then the same as the type of the hypothetical identifier. \begin{example} \begin{codeblock} int // \tcode{int i} int * // \tcode{int *pi} int *[3] // \tcode{int *p[3]} int (*)[3] // \tcode{int (*p3i)[3]} int *() // \tcode{int *f()} int (*)(double) // \tcode{int (*pf)(double)} \end{codeblock} name respectively the types ``\tcode{int}'', ``pointer to \tcode{int}'', ``array of 3 pointers to \tcode{int}'', ``pointer to array of 3 \tcode{int}'', ``function of (no parameters) returning pointer to \tcode{int}'', and ``pointer to a function of (\tcode{double}) returning \tcode{int}''. \end{example} \pnum A type can also be named (often more easily) by using a \tcode{typedef}\iref{dcl.typedef}. \rSec2[dcl.ambig.res]{Ambiguity resolution}% \indextext{ambiguity!declaration versus cast}% \indextext{declaration!parentheses in} \pnum The ambiguity arising from the similarity between a function-style cast and a declaration mentioned in~\ref{stmt.ambig} can also occur in the context of a declaration. In that context, the choice is between an object declaration with a function-style cast as the initializer and a declaration involving a function declarator with a redundant set of parentheses around a parameter name. Just as for the ambiguities mentioned in~\ref{stmt.ambig}, the resolution is to consider any construct, such as the potential parameter declaration, that could possibly be a declaration to be a declaration. \begin{note} A declaration can be explicitly disambiguated by adding parentheses around the argument. The ambiguity can be avoided by use of copy-initialization or list-initialization syntax, or by use of a non-function-style cast. \end{note} \begin{example} \begin{codeblock} struct S { S(int); }; void foo(double a) { S w(int(a)); // function declaration S x(int()); // function declaration S y((int(a))); // object declaration S y((int)a); // object declaration S z = int(a); // object declaration } \end{codeblock} \end{example} \pnum An ambiguity can arise from the similarity between a function-style cast and a \grammarterm{type-id}. The resolution is that any construct that could possibly be a \grammarterm{type-id} in its syntactic context shall be considered a \grammarterm{type-id}. \begin{example} \begin{codeblock} template struct X {}; template struct Y {}; X a; // type-id X b; // expression (ill-formed) Y c; // type-id (ill-formed) Y d; // expression void foo(signed char a) { sizeof(int()); // type-id (ill-formed) sizeof(int(a)); // expression sizeof(int(unsigned(a))); // type-id (ill-formed) (int())+1; // type-id (ill-formed) (int(a))+1; // expression (int(unsigned(a)))+1; // type-id (ill-formed) } \end{codeblock} \end{example} \pnum Another ambiguity arises in a \grammarterm{parameter-declaration-clause} when a \grammarterm{type-name} is nested in parentheses. In this case, the choice is between the declaration of a parameter of type pointer to function and the declaration of a parameter with redundant parentheses around the \grammarterm{declarator-id}. The resolution is to consider the \grammarterm{type-name} as a \grammarterm{simple-type-specifier} rather than a \grammarterm{declarator-id}. \begin{example} \begin{codeblock} class C { }; void f(int(C)) { } // \tcode{void f(int(*fp)(C c)) \{ \}} // not: \tcode{void f(int C) \{ \}} int g(C); void foo() { f(1); // error: cannot convert \tcode{1} to function pointer f(g); // OK } \end{codeblock} For another example, \begin{codeblock} class C { }; void h(int *(C[10])); // \tcode{void h(int *(*_fp)(C _parm[10]));} // not: \tcode{void h(int *C[10]);} \end{codeblock} \end{example} \rSec2[dcl.meaning]{Meaning of declarators}% \rSec3[dcl.meaning.general]{General}% \indextext{declarator!meaning of|(} \pnum \indextext{declaration!type}% A declarator contains exactly one \grammarterm{declarator-id}; it names the entity that is declared. If the \grammarterm{unqualified-id} occurring in a \grammarterm{declarator-id} is a \grammarterm{template-id}, the declarator shall appear in the \grammarterm{declaration} of a \grammarterm{template-declaration}\iref{temp.decls}, \grammarterm{explicit-specialization}\iref{temp.expl.spec}, or \grammarterm{explicit-instantiation}\iref{temp.explicit}. \begin{note} An \grammarterm{unqualified-id} that is not an \grammarterm{identifier} is used to declare certain functions\iref{class.conv.fct,class.dtor,over.oper,over.literal}. \end{note} The optional \grammarterm{attribute-specifier-seq} following a \grammarterm{declarator-id} appertains to the entity that is declared. \pnum If the declaration is a friend declaration: \begin{itemize} \item The \grammarterm{declarator} does not bind a name. \item If the \grammarterm{id-expression} $E$ in the \grammarterm{declarator-id} of the \grammarterm{declarator} is a \grammarterm{qualified-id} or a \grammarterm{template-id}: \begin{itemize} \item If the friend declaration is not a template declaration, then in the lookup for the terminal name of $E$: \begin{itemize} \item if the \grammarterm{unqualified-id} in $E$ is a \grammarterm{template-id}, all function declarations are discarded; \item otherwise, if the \grammarterm{declarator} corresponds\iref{basic.scope.scope} to any declaration found of a non-template function, all function template declarations are discarded; \item each remaining function template is replaced with the specialization chosen by deduction from the friend declaration\iref{temp.deduct.decl} or discarded if deduction fails. \end{itemize} \item The \grammarterm{declarator} 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 \grammarterm{declarator} is that scope. \end{itemize} \item Otherwise, the terminal name of $E$ is not looked up. 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\iref{module.reach} declaration that inhabits the innermost block scope. \end{itemize} \pnum Otherwise: \begin{itemize} \item If the \grammarterm{id-expression} in the \grammarterm{declarator-id} of the \grammarterm{declarator} is a \grammarterm{qualified-id} $Q$, let $S$ be its lookup context\iref{basic.lookup.qual}; the declaration shall inhabit a namespace scope. \item Otherwise, let $S$ be the entity associated with the scope inhabited by the \grammarterm{declarator}. \item If the \grammarterm{declarator} declares an explicit instantiation or a partial or explicit specialization, the \grammarterm{declarator} does not bind a name. If it declares a class member, the terminal name of the \grammarterm{declarator-id} is not looked up; otherwise, only those lookup results that are nominable in $S$ are considered when identifying any function template specialization being declared\iref{temp.deduct.decl}. \begin{example} \begin{codeblock} namespace N { inline namespace O { template void f(T); // \#1 template void g(T) {} } namespace P { template void f(T*); // \#2, more specialized than \#1 template int g; } using P::f,P::g; } template<> void N::f(int*) {} // OK, \#2 is not nominable template void N::g(int); // error: lookup is ambiguous \end{codeblock} \end{example} \item Otherwise, the terminal name of the \grammarterm{declarator-id} is not looked up. If it is a qualified name, the \grammarterm{declarator} 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 \grammarterm{declarator} is that scope. \begin{example} \begin{codeblock} namespace Q { namespace V { void f(); } void V::f() { @\commentellip@ } // OK void V::g() { @\commentellip@ } // error: \tcode{g()} is not yet a member of \tcode{V} namespace V { void g(); } } namespace R { void Q::V::g() { @\commentellip@ } // error: \tcode{R} doesn't enclose \tcode{Q} } \end{codeblock} \end{example} \item If the declaration inhabits a block scope $S$ and declares a function\iref{dcl.fct} or uses the \keyword{extern} specifier, the declaration shall not be attached to a named module\iref{module.unit}; its target scope is the innermost enclosing namespace scope, but the name is bound in $S$. \begin{example} \begin{codeblock} namespace X { void p() { q(); // error: \tcode{q} not yet declared extern void q(); // \tcode{q} is a member of namespace \tcode{X} extern void r(); // \tcode{r} is a member of namespace \tcode{X} } void middle() { q(); // error: \tcode{q} not found } void q() { @\commentellip@ } // definition of \tcode{X::q} } void q() { @\commentellip@ } // some other, unrelated \tcode{q} void X::r() { @\commentellip@ } // error: \tcode{r} cannot be declared by \grammarterm{qualified-id} \end{codeblock} \end{example} \end{itemize} \pnum A \keyword{static}, \keyword{thread_local}, \keyword{extern}, \keyword{mutable}, \keyword{friend}, \keyword{inline}, \keyword{virtual}, \keyword{constexpr}, \keyword{consteval}, \keyword{constinit}, or \tcode{typedef} specifier or an \grammarterm{explicit-specifier} applies directly to each \grammarterm{declarator-id} in a declaration; the type specified for each \grammarterm{declarator-id} depends on both the \grammarterm{decl-specifier-seq} and its \grammarterm{declarator}. \pnum Thus, (for each \grammarterm{declarator}) a declaration has the form \begin{codeblock} T D \end{codeblock} where \tcode{T} is of the form \opt{\grammarterm{attribute-specifier-seq}} \grammarterm{decl-specifier-seq} and \tcode{D} is a declarator. Following is a recursive procedure for determining the type specified for the contained \grammarterm{declarator-id} by such a declaration. \pnum First, the \grammarterm{decl-specifier-seq} determines a type. In a declaration \begin{codeblock} T D \end{codeblock} the \grammarterm{decl-specifier-seq} \tcode{T} determines the type \tcode{T}. \begin{example} In the declaration \begin{codeblock} int unsigned i; \end{codeblock} the type specifiers \tcode{int} \tcode{unsigned} determine the type ``\tcode{unsigned int}''\iref{dcl.type.simple}. \end{example} \pnum In a declaration \opt{\grammarterm{attribute-specifier-seq}} \tcode{T} \tcode{D} where \tcode{D} is an unadorned name, the type of the declared entity is ``\tcode{T}''. \pnum In a declaration \tcode{T} \tcode{D} where \tcode{D} has the form \begin{ncsimplebnf} \terminal{(} \terminal{D1} \terminal{)} \end{ncsimplebnf} the type of the contained \grammarterm{declarator-id} is the same as that of the contained \grammarterm{declarator-id} in the declaration \begin{codeblock} T D1 \end{codeblock} \indextext{declaration!parentheses in}% Parentheses do not alter the type of the embedded \grammarterm{declarator-id}, but they can alter the binding of complex declarators. \rSec3[dcl.ptr]{Pointers}% \indextext{declarator!pointer}% \pnum In a declaration \tcode{T} \tcode{D} where \tcode{D} has the form \begin{ncsimplebnf} \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \terminal{D1} \end{ncsimplebnf} and the type of the contained \grammarterm{declarator-id} in the declaration \tcode{T} \tcode{D1} is ``\placeholder{derived-declarator-type-list} \tcode{T}'', the type of the \grammarterm{declarator-id} in \tcode{D} is ``\placeholder{derived-declarator-type-list} \grammarterm{cv-qualifier-seq} pointer to \tcode{T}''. \indextext{declaration!pointer}% \indextext{declaration!constant pointer}% The \grammarterm{cv-qualifier}{s} apply to the pointer and not to the object pointed to. Similarly, the optional \grammarterm{attribute-specifier-seq}\iref{dcl.attr.grammar} appertains to the pointer and not to the object pointed to. \pnum \begin{example} The declarations \begin{codeblock} const int ci = 10, *pc = &ci, *const cpc = pc, **ppc; int i, *p, *const cp = &i; \end{codeblock} declare \tcode{ci}, a constant integer; \tcode{pc}, a pointer to a constant integer; \tcode{cpc}, a constant pointer to a constant integer; \tcode{ppc}, a pointer to a pointer to a constant integer; \tcode{i}, an integer; \tcode{p}, a pointer to integer; and \tcode{cp}, a constant pointer to integer. The value of \tcode{ci}, \tcode{cpc}, and \tcode{cp} cannot be changed after initialization. The value of \tcode{pc} can be changed, and so can the object pointed to by \tcode{cp}. Examples of some correct operations are \begin{codeblock} i = ci; *cp = ci; pc++; pc = cpc; pc = p; ppc = &pc; \end{codeblock} Examples of ill-formed operations are \begin{codeblock} ci = 1; // error ci++; // error *pc = 2; // error cp = &ci; // error cpc++; // error p = pc; // error ppc = &p; // error \end{codeblock} Each is unacceptable because it would either change the value of an object declared \keyword{const} or allow it to be changed through a cv-unqualified pointer later, for example: \begin{codeblock} *ppc = &ci; // OK, but would make \tcode{p} point to \tcode{ci} because of previous error *p = 5; // clobber \tcode{ci} \end{codeblock} \end{example} \pnum See also~\ref{expr.ass} and~\ref{dcl.init}. \pnum \begin{note} Forming a pointer to reference type is ill-formed; see~\ref{dcl.ref}. Forming a function pointer type is ill-formed if the function type has \grammarterm{cv-qualifier}{s} or a \grammarterm{ref-qualifier}; see~\ref{dcl.fct}. Since the address of a bit-field\iref{class.bit} cannot be taken, a pointer can never point to a bit-field. \end{note} \rSec3[dcl.ref]{References}% \indextext{declarator!reference} \pnum In a declaration \tcode{T} \tcode{D} where \tcode{D} has either of the forms \begin{ncsimplebnf} \terminal{\&} \opt{attribute-specifier-seq} \terminal{D1}\br \terminal{\&\&} \opt{attribute-specifier-seq} \terminal{D1} \end{ncsimplebnf} and the type of the contained \grammarterm{declarator-id} in the declaration \tcode{T} \tcode{D1} is ``\placeholder{derived-declarator-type-list} \tcode{T}'', the type of the \grammarterm{declarator-id} in \tcode{D} is ``\placeholder{derived-declarator-type-list} reference to \tcode{T}''. The optional \grammarterm{attribute-specifier-seq} appertains to the reference type. Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a \grammarterm{typedef-name}\iref{dcl.typedef,temp.param} or \grammarterm{decltype-specifier}\iref{dcl.type.decltype}, in which case the cv-qualifiers are ignored. \begin{example} \begin{codeblock} typedef int& A; const A aref = 3; // error: lvalue reference to non-\keyword{const} initialized with rvalue \end{codeblock} The type of \tcode{aref} is ``lvalue reference to \tcode{int}'', not ``lvalue reference to \tcode{const int}''. \end{example} \begin{note} A reference can be thought of as a name of an object. \end{note} \indextext{\idxcode{void\&}}% A declarator that specifies the type ``reference to \cv{}~\keyword{void}'' is ill-formed. \pnum A reference type that is declared using \tcode{\&} is called an \defn{lvalue reference}, and a reference type that is declared using \tcode{\&\&} is called an \defn{rvalue reference}. Lvalue references and rvalue references are distinct types. Except where explicitly noted, they are semantically equivalent and commonly referred to as references. \pnum \indextext{declaration!reference}% \indextext{parameter!reference}% \begin{example} \begin{codeblock} void f(double& a) { a += 3.14; } // ... double d = 0; f(d); \end{codeblock} declares \tcode{a} to be a reference parameter of \tcode{f} so the call \tcode{f(d)} will add \tcode{3.14} to \tcode{d}. \begin{codeblock} int v[20]; // ... int& g(int i) { return v[i]; } // ... g(3) = 7; \end{codeblock} declares the function \tcode{g()} to return a reference to an integer so \tcode{g(3)=7} will assign \tcode{7} to the fourth element of the array \tcode{v}. For another example, \begin{codeblock} struct link { link* next; }; link* first; void h(link*& p) { // \tcode{p} is a reference to pointer p->next = first; first = p; p = 0; } void k() { link* q = new link; h(q); } \end{codeblock} declares \tcode{p} to be a reference to a pointer to \tcode{link} so \tcode{h(q)} will leave \tcode{q} with the value zero. See also~\ref{dcl.init.ref}. \end{example} \pnum It is unspecified whether or not a reference requires storage\iref{basic.stc}. \pnum \indextext{restriction!reference}% There shall be no references to references, no arrays of references, and no pointers to references. \indextext{initialization!reference}% The declaration of a reference shall contain an \grammarterm{initializer}\iref{dcl.init.ref} except when the declaration contains an explicit \keyword{extern} specifier\iref{dcl.stc}, is a class member\iref{class.mem} declaration within a class definition, or is the declaration of a parameter or a return type\iref{dcl.fct}; see~\ref{basic.def}. A reference shall be initialized to refer to a valid object or function. \begin{note} \indextext{reference!null}% In particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the ``object'' obtained by indirection through a null pointer, which causes undefined behavior. As described in~\ref{class.bit}, a reference cannot be bound directly to a bit-field. \end{note} \pnum \indextext{reference collapsing}% If a \grammarterm{typedef-name}\iref{dcl.typedef,temp.param} or a \grammarterm{decltype-specifier}\iref{dcl.type.decltype} denotes a type \tcode{TR} that is a reference to a type \tcode{T}, an attempt to create the type ``lvalue reference to \cv{}~\tcode{TR}'' creates the type ``lvalue reference to \tcode{T}'', while an attempt to create the type ``rvalue reference to \cv{}~\tcode{TR}'' creates the type \tcode{TR}. \begin{note} This rule is known as reference collapsing. \end{note} \begin{example} \begin{codeblock} int i; typedef int& LRI; typedef int&& RRI; LRI& r1 = i; // \tcode{r1} has the type \tcode{int\&} const LRI& r2 = i; // \tcode{r2} has the type \tcode{int\&} const LRI&& r3 = i; // \tcode{r3} has the type \tcode{int\&} RRI& r4 = i; // \tcode{r4} has the type \tcode{int\&} RRI&& r5 = 5; // \tcode{r5} has the type \tcode{int\&\&} decltype(r2)& r6 = i; // \tcode{r6} has the type \tcode{int\&} decltype(r2)&& r7 = i; // \tcode{r7} has the type \tcode{int\&} \end{codeblock} \end{example} \pnum \begin{note} Forming a reference to function type is ill-formed if the function type has \grammarterm{cv-qualifier}{s} or a \grammarterm{ref-qualifier}; see~\ref{dcl.fct}. \end{note} \rSec3[dcl.mptr]{Pointers to members}% \indextext{declarator!pointer-to-member}% \indextext{pointer to member}% \pnum \indextext{component name}% The component names of a \grammarterm{ptr-operator} are those of its \grammarterm{nested-name-specifier}, if any. \pnum In a declaration \tcode{T} \tcode{D} where \tcode{D} has the form \begin{ncsimplebnf} nested-name-specifier \terminal{*} \opt{attribute-specifier-seq} \opt{cv-qualifier-seq} \terminal{D1} \end{ncsimplebnf} and the \grammarterm{nested-name-specifier} denotes a class, and the type of the contained \grammarterm{declarator-id} in the declaration \tcode{T} \tcode{D1} is ``\placeholder{derived-declarator-type-list} \tcode{T}'', the type of the \grammarterm{declarator-id} in \tcode{D} is ``\placeholder{derived-declarator-type-list} \grammarterm{cv-qualifier-seq} pointer to member of class \grammarterm{nested-name-specifier} of type \tcode{T}''. The optional \grammarterm{attribute-specifier-seq}\iref{dcl.attr.grammar} appertains to the pointer-to-member. \pnum \begin{example} \begin{codeblock} 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; \end{codeblock} declares \tcode{pmi}, \tcode{pmf}, \tcode{pmd} and \tcode{pmc} to be a pointer to a member of \tcode{X} of type \tcode{int}, a pointer to a member of \tcode{X} of type \tcode{void(int)}, a pointer to a member of \tcode{X} of type \tcode{double} and a pointer to a member of \tcode{Y} of type \tcode{char} respectively. The declaration of \tcode{pmd} is well-formed even though \tcode{X} has no members of type \tcode{double}. Similarly, the declaration of \tcode{pmc} is well-formed even though \tcode{Y} is an incomplete type. \tcode{pmi} and \tcode{pmf} can be used like this: \begin{codeblock} X obj; // ... obj.*pmi = 7; // assign \tcode{7} to an integer member of \tcode{obj} (obj.*pmf)(7); // call a function member of \tcode{obj} with the argument \tcode{7} \end{codeblock} \end{example} \pnum A pointer to member shall not point to a static member of a class\iref{class.static}, a member with reference type, or ``\cv{}~\keyword{void}''. \pnum \begin{note} See also~\ref{expr.unary} and~\ref{expr.mptr.oper}. 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. There is no ``reference-to-member'' type in \Cpp{}. \end{note} \rSec3[dcl.array]{Arrays}% \indextext{declarator!array} \pnum In a declaration \tcode{T} \tcode{D} where \tcode{D} has the form \begin{ncsimplebnf} \terminal{D1} \terminal{[} \opt{constant-expression} \terminal{]} \opt{attribute-specifier-seq} \end{ncsimplebnf} and the type of the contained \grammarterm{declarator-id} in the declaration \tcode{T} \tcode{D1} is ``\placeholder{derived-declarator-type-list} \tcode{T}'', the type of the \grammarterm{declarator-id} in \tcode{D} is ``\placeholder{derived-declarator-type-list} array of \tcode{N} \tcode{T}''. The \grammarterm{constant-expression} shall be a converted constant expression of type \tcode{std::size_t}\iref{expr.const}. \indextext{bound, of array}% Its value \tcode{N} specifies the \defnx{array bound}{array!bound}, i.e., the number of elements in the array; \tcode{N} shall be greater than zero. \pnum In a declaration \tcode{T} \tcode{D} where \tcode{D} has the form \begin{ncsimplebnf} \terminal{D1 [ ]} \opt{attribute-specifier-seq} \end{ncsimplebnf} and the type of the contained \grammarterm{declarator-id} in the declaration \tcode{T} \tcode{D1} is ``\placeholder{derived-declarator-type-list} \tcode{T}'', the type of the \grammarterm{declarator-id} in \tcode{D} is ``\placeholder{derived-declarator-type-list} array of unknown bound of \tcode{T}'', except as specified below. \pnum \indextext{declaration!array}% \label{term.array.type}% A type of the form ``array of \tcode{N} \tcode{U}'' or ``array of unknown bound of \tcode{U}'' is an \defn{array type}. The optional \grammarterm{attribute-specifier-seq} appertains to the array type. \pnum \tcode{U} is called the array \defn{element type}; this type shall not be a reference type, a function type, an array of unknown bound, or \cv{}~\keyword{void}. \begin{note} An array can be constructed from one of the fundamental types (except \keyword{void}), from a pointer, from a pointer to member, from a class, from an enumeration type, or from an array of known bound. \end{note} \begin{example} \begin{codeblock} float fa[17], *afp[17]; \end{codeblock} declares an array of \tcode{float} numbers and an array of pointers to \tcode{float} numbers. \end{example} \pnum Any type of the form ``\grammarterm{cv-qualifier-seq} array of \tcode{N} \tcode{U}'' is adjusted to ``array of \tcode{N} \grammarterm{cv-qualifier-seq} \tcode{U}'', and similarly for ``array of unknown bound of \tcode{U}''. \begin{example} \begin{codeblock} typedef int A[5], AA[2][3]; typedef const A CA; // type is ``array of 5 \tcode{const int}'' typedef const AA CAA; // type is ``array of 2 array of 3 \tcode{const int}'' \end{codeblock} \end{example} \begin{note} An ``array of \tcode{N} \grammarterm{cv-qualifier-seq} \tcode{U}'' has cv-qualified type; see~\ref{basic.type.qualifier}. \end{note} \pnum An object of type ``array of \tcode{N} \tcode{U}'' consists of a contiguously allocated non-empty set of \tcode{N} subobjects of type \tcode{U}, known as the \defnx{elements}{array!element} of the array, and numbered \tcode{0} to \tcode{N-1}. \pnum 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\iref{dcl.fct}. 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\iref{dcl.init,class.mem,expr.type.conv,expr.new}. \indextext{array size!default}% In these cases, the array bound is calculated from the number of initial elements (say, \tcode{N}) supplied\iref{dcl.init.aggr}, and the type of the array is ``array of \tcode{N} \tcode{U}''. \pnum Furthermore, if there is a reachable declaration of the entity that inhabits the same scope in which the bound was specified, 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. \begin{example} \begin{codeblock} extern int x[10]; struct S { static int y[10]; }; int x[]; // OK, bound is 10 int S::y[]; // OK, bound is 10 void f() { extern int x[]; int i = sizeof(x); // error: incomplete object type } \end{codeblock} \end{example} \pnum \indextext{declarator!multidimensional array}% \begin{note} 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. \begin{example} \begin{codeblock} int x3d[3][5][7]; \end{codeblock} declares an array of three elements, each of which is an array of five elements, each of which is an array of seven integers. The overall array can be viewed as a three-dimensional array of integers, with rank $3 \times 5 \times 7$. Any of the expressions \tcode{x3d}, \tcode{x3d[i]}, \tcode{x3d[i][j]}, \tcode{x3d[i][j][k]} can reasonably appear in an expression. The expression \tcode{x3d[i]} is equivalent to \tcode{*(x3d + i)}; in that expression, \tcode{x3d} is subject to the array-to-pointer conversion\iref{conv.array} and is first converted to a pointer to a 2-dimensional array with rank $5 \times 7$ that points to the first element of \tcode{x3d}. Then \tcode{i} is added, which on typical implementations involves multiplying \tcode{i} by the length of the object to which the pointer points, which is \tcode{sizeof(int)}$ \times 5 \times 7$. The result of the addition and indirection is an lvalue denoting the $\tcode{i}^\text{th}$ array element of \tcode{x3d} (an array of five arrays of seven integers). If there is another subscript, the same argument applies again, so \tcode{x3d[i][j]} is an lvalue denoting the $\tcode{j}^\text{th}$ array element of the $\tcode{i}^\text{th}$ array element of \tcode{x3d} (an array of seven integers), and \tcode{x3d[i][j][k]} is an lvalue denoting the $\tcode{k}^\text{th}$ array element of the $\tcode{j}^\text{th}$ array element of the $\tcode{i}^\text{th}$ array element of \tcode{x3d} (an integer). \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. \end{note} \pnum \begin{note} Conversions affecting expressions of array type are described in~\ref{conv.array}. \end{note} \pnum \begin{note} The subscript operator can be overloaded for a class\iref{over.sub}. For the operator's built-in meaning, see \ref{expr.sub}. \end{note} \rSec3[dcl.fct]{Functions}% \indextext{declarator!function|(} \pnum \indextext{type!function}% In a declaration \tcode{T} \tcode{D} where \tcode{D} has the form \begin{ncsimplebnf} \terminal{D1} \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br \bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \end{ncsimplebnf} and the type of the contained \grammarterm{declarator-id} in the declaration \tcode{T} \tcode{D1} is ``\placeholder{derived-declarator-type-list} \tcode{T}'', the type of the \grammarterm{declarator-id} in \tcode{D} is ``\placeholder{derived-declarator-type-list} \opt{\keyword{noexcept}} function of parameter-type-list \opt{\grammarterm{cv-qualifier-seq}} \opt{\grammarterm{ref-qualifier}} returning \tcode{T}'', where \begin{itemize} \item the parameter-type-list is derived from the \grammarterm{parameter-declaration-clause} as described below and \item the optional \keyword{noexcept} is present if and only if the exception specification\iref{except.spec} is non-throwing. \end{itemize} The optional \grammarterm{attribute-specifier-seq} appertains to the function type. \pnum In a declaration \tcode{T} \tcode{D} where \tcode{D} has the form \begin{ncsimplebnf} \terminal{D1} \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br \bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} trailing-return-type \end{ncsimplebnf} and the type of the contained \grammarterm{declarator-id} in the declaration \tcode{T} \tcode{D1} is ``\placeholder{derived-declarator-type-list} \tcode{T}'', \tcode{T} shall be the single \grammarterm{type-specifier} \keyword{auto}. The type of the \grammarterm{declarator-id} in \tcode{D} is ``\placeholder{derived-declarator-type-list} \opt{\keyword{noexcept}} function of parameter-type-list \opt{\grammarterm{cv-qualifier-seq}} \opt{\grammarterm{ref-qualifier}} returning \tcode{U}'', where \begin{itemize} \item the parameter-type-list is derived from the \grammarterm{parameter-declaration-clause} as described below, \item \tcode{U} is the type specified by the \grammarterm{trailing-return-type}, and \item the optional \keyword{noexcept} is present if and only if the exception specification is non-throwing. \end{itemize} The optional \grammarterm{attribute-specifier-seq} appertains to the function type. \pnum \indextext{type!function}% A type of either form is a \term{function type}.% \begin{footnote} As indicated by syntax, cv-qualifiers are a significant component in function return types. \end{footnote} \indextext{declaration!function}% \begin{bnf} \nontermdef{parameter-declaration-clause}\br \opt{parameter-declaration-list} \opt{\terminal{...}}\br parameter-declaration-list \terminal{,} \terminal{...} \end{bnf} \begin{bnf} \nontermdef{parameter-declaration-list}\br parameter-declaration\br parameter-declaration-list \terminal{,} parameter-declaration \end{bnf} \begin{bnf} \nontermdef{parameter-declaration}\br \opt{attribute-specifier-seq} \opt{\keyword{this}} decl-specifier-seq declarator\br \opt{attribute-specifier-seq} decl-specifier-seq declarator \terminal{=} initializer-clause\br \opt{attribute-specifier-seq} \opt{\keyword{this}} decl-specifier-seq \opt{abstract-declarator}\br \opt{attribute-specifier-seq} decl-specifier-seq \opt{abstract-declarator} \terminal{=} initializer-clause \end{bnf} The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{parameter-declaration} appertains to the parameter. \pnum \indextext{declaration!parameter}% The \grammarterm{parameter-declaration-clause} determines the arguments that can be specified, and their processing, when the function is called. \begin{note} \indextext{conversion!argument}% The \grammarterm{parameter-declaration-clause} is used to convert the arguments specified on the function call; see~\ref{expr.call}. \end{note} \indextext{argument list!empty}% If the \grammarterm{parameter-declaration-clause} is empty, the function takes no arguments. A parameter list consisting of a single unnamed parameter of non-dependent type \keyword{void} is equivalent to an empty parameter list. \indextext{parameter!\idxcode{void}}% Except for this special case, a parameter shall not have type \cv{}~\keyword{void}. A parameter with volatile-qualified type is deprecated; see~\ref{depr.volatile.type}. If the \grammarterm{parameter-declaration-clause} \indextext{argument type!unknown}% \indextext{\idxcode{...}|see{ellipsis}}% \indextext{declaration!ellipsis in function}% \indextext{argument list!variable}% \indextext{parameter list!variable}% terminates with an ellipsis or a function parameter pack\iref{temp.variadic}, 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. Where syntactically correct and where ``\tcode{...}'' is not part of an \grammarterm{abstract-declarator}, ``\tcode{, ...}'' is synonymous with ``\tcode{...}''. \begin{example} The declaration \begin{codeblock} int printf(const char*, ...); \end{codeblock} declares a function that can be called with varying numbers and types of arguments. \begin{codeblock} printf("hello world"); printf("a=%d b=%d", a, b); \end{codeblock} However, the first argument must be of a type that can be converted to a \keyword{const} \tcode{char*}. \end{example} \begin{note} The standard header \libheaderref{cstdarg} contains a mechanism for accessing arguments passed using the ellipsis (see~\ref{expr.call} and~\ref{support.runtime}). \end{note} \pnum \indextext{type!function}% The type of a function is determined using the following rules. The type of each parameter (including function parameter packs) is determined from its own \grammarterm{parameter-declaration}\iref{dcl.decl}. After determining the type of each parameter, any parameter \indextext{array!parameter of type}% of type ``array of \tcode{T}'' or \indextext{function!parameter of type}% of function type \tcode{T} is adjusted to be ``pointer to \tcode{T}''. After producing the list of parameter types, any top-level \grammarterm{cv-qualifier}{s} modifying a parameter type are deleted when forming the function type. The resulting list of transformed parameter types and the presence or absence of the ellipsis or a function parameter pack is the function's \defn{parameter-type-list}. \begin{note} This transformation does not affect the types of the parameters. For example, \tcode{int(*)(const int p, decltype(p)*)} and \tcode{int(*)(int, const int*)} are identical types. \end{note} \begin{example} \begin{codeblock} void f(char*); // \#1 void f(char[]) {} // defines \#1 void f(const char*) {} // OK, another overload void f(char *const) {} // error: redefines \#1 void g(char(*)[2]); // \#2 void g(char[3][2]) {} // defines \#2 void g(char[3][3]) {} // OK, another overload void h(int x(const int)); // \#3 void h(int (*)(int)) {} // defines \#3 \end{codeblock} \end{example} \pnum An \defn{explicit-object-parameter-declaration} is a \grammarterm{parameter-declaration} with a \keyword{this} specifier. An explicit-object-parameter-declaration shall appear only as the first \grammarterm{parameter-declaration} of a \grammarterm{parameter-declaration-list} of either: \begin{itemize} \item a \grammarterm{member-declarator} that declares a member function\iref{class.mem}, or \item a \grammarterm{lambda-declarator}\iref{expr.prim.lambda}. \end{itemize} A \grammarterm{member-declarator} with an explicit-object-parameter-declaration shall not include a \grammarterm{ref-qualifier} or a \grammarterm{cv-qualifier-seq} and shall not be declared \keyword{static} or \keyword{virtual}. \begin{example} \begin{codeblock} struct C { void f(this C& self); template void g(this Self&& self, int); void h(this C) const; // error: \tcode{const} not allowed here }; void test(C c) { c.f(); // OK, calls \tcode{C::f} c.g(42); // OK, calls \tcode{C::g} std::move(c).g(42); // OK, calls \tcode{C::g} } \end{codeblock} \end{example} \pnum A function parameter declared with an explicit-object-parameter-declaration is an \defnadj{explicit object}{parameter}. An explicit object parameter shall not be a function parameter pack\iref{temp.variadic}. An \defnadj{explicit object}{member function} is a non-static member function with an explicit object parameter. An \defnadj{implicit object}{member function} is a non-static member function without an explicit object parameter. \pnum The \defnadj{object}{parameter} of a non-static member function is either the explicit object parameter or the implicit object parameter\iref{over.match.funcs}. \pnum A \defnadj{non-object}{parameter} is a function parameter that is not the explicit object parameter. The \defn{non-object-parameter-type-list} of a member function is the parameter-type-list of that function with the explicit object parameter, if any, omitted. \begin{note} The non-object-parameter-type-list consists of the adjusted types of all the non-object parameters. \end{note} \pnum A function type with a \grammarterm{cv-qualifier-seq} or a \grammarterm{ref-qualifier} (including a type named by \grammarterm{typedef-name}\iref{dcl.typedef,temp.param}) shall appear only as: \begin{itemize} \item the function type for a non-static member function, \item the function type to which a pointer to member refers, \item the top-level function type of a function typedef declaration or \grammarterm{alias-declaration}, \item the \grammarterm{type-id} in the default argument of a \grammarterm{type-parameter}\iref{temp.param}, or \item the \grammarterm{type-id} of a \grammarterm{template-argument} for a \grammarterm{type-parameter}\iref{temp.arg.type}. \end{itemize} \begin{example} \begin{codeblock} typedef int FIC(int) const; FIC f; // error: does not declare a member function struct S { FIC f; // OK }; FIC S::*pm = &S::f; // OK \end{codeblock} \end{example} \pnum The effect of a \grammarterm{cv-qualifier-seq} in a function declarator is not the same as adding cv-qualification on top of the function type. In the latter case, the cv-qualifiers are ignored. \begin{note} A function type that has a \grammarterm{cv-qualifier-seq} is not a cv-qualified type; there are no cv-qualified function types. \end{note} \begin{example} \begin{codeblock} typedef void F(); struct S { const F f; // OK, equivalent to: \tcode{void f();} }; \end{codeblock} \end{example} \pnum The return type, the parameter-type-list, the \grammarterm{ref-qualifier}, the \grammarterm{cv-qualifier-seq}, and the exception specification, but not the default arguments\iref{dcl.fct.default} or the trailing \grammarterm{requires-clause}\iref{dcl.decl}, are part of the function type. \begin{note} Function types are checked during the assignments and initializations of pointers to functions, references to functions, and pointers to member functions. \end{note} \pnum \begin{example} The declaration \begin{codeblock} int fseek(FILE*, long, int); \end{codeblock} declares a function taking three arguments of the specified types, and returning \tcode{int}\iref{dcl.type}. \end{example} \pnum \indextext{overloading}% \begin{note} A single name can be used for several different functions in a single scope; this is function overloading\iref{over}. \end{note} \pnum \indextext{function return type|see{return type}}% \indextext{return type}% The return type shall be a non-array object type, a reference type, or \cv{}~\keyword{void}. \begin{note} An array of placeholder type is considered an array type. \end{note} \pnum A volatile-qualified return type is deprecated; see~\ref{depr.volatile.type}. \pnum Types shall not be defined in return or parameter types. \pnum \indextext{typedef!function}% A typedef of function type may be used to declare a function but shall not be used to define a function\iref{dcl.fct.def}. \begin{example} \begin{codeblock} typedef void F(); F fv; // OK, equivalent to \tcode{void fv();} F fv { } // error void fv() { } // OK, definition of \tcode{fv} \end{codeblock} \end{example} \pnum An identifier can optionally be provided as a parameter name; if present in a function definition\iref{dcl.fct.def}, it names a parameter. \begin{note} 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. \end{note} \pnum \begin{example} The declaration \begin{codeblock} int i, *pi, f(), *fpi(int), (*pif)(const char*, const char*), (*fpif(int))(int); \end{codeblock} declares an integer \tcode{i}, a pointer \tcode{pi} to an integer, a function \tcode{f} taking no arguments and returning an integer, a function \tcode{fpi} taking an integer argument and returning a pointer to an integer, a pointer \tcode{pif} to a function which takes two pointers to constant characters and returns an integer, a function \tcode{fpif} taking an integer argument and returning a pointer to a function that takes an integer argument and returns an integer. It is especially useful to compare \tcode{fpi} and \tcode{pif}. The binding of \tcode{*fpi(int)} is \tcode{*(fpi(int))}, so the declaration suggests, and the same construction in an expression requires, the calling of a function \tcode{fpi}, and then using indirection through the (pointer) result to yield an integer. In the declarator \tcode{(*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. \end{example} \begin{note} Typedefs and \grammarterm{trailing-return-type}{s} are sometimes convenient when the return type of a function is complex. For example, the function \tcode{fpif} above can be declared \begin{codeblock} typedef int IFUNC(int); IFUNC* fpif(int); \end{codeblock} or \begin{codeblock} auto fpif(int)->int(*)(int); \end{codeblock} A \grammarterm{trailing-return-type} is most useful for a type that would be more complicated to specify before the \grammarterm{declarator-id}: \begin{codeblock} template auto add(T t, U u) -> decltype(t + u); \end{codeblock} rather than \begin{codeblock} template decltype((*(T*)0) + (*(U*)0)) add(T t, U u); \end{codeblock} \end{note} \pnum A \defnadj{non-template}{function} is a function that is not a function template specialization. \begin{note} A function template is not a function. \end{note} \pnum \indextext{abbreviated!template function|see{template, function, abbreviated}}% An \defnx{abbreviated function template}{template!function!abbreviated} is a function declaration that has one or more generic parameter type placeholders\iref{dcl.spec.auto}. An abbreviated function template is equivalent to a function template\iref{temp.fct} whose \grammarterm{template-parameter-list} includes one invented type \grammarterm{template-parameter} for each generic parameter type placeholder of the function declaration, in order of appearance. For a \grammarterm{placeholder-type-specifier} of the form \keyword{auto}, the invented parameter is an unconstrained \grammarterm{type-parameter}. For a \grammarterm{placeholder-type-specifier} of the form \grammarterm{type-constraint} \keyword{auto}, the invented parameter is a \grammarterm{type-parameter} with that \grammarterm{type-constraint}. The invented type \grammarterm{template-parameter} is a template parameter pack if the corresponding \grammarterm{parameter-declaration} declares a function parameter pack. If the placeholder contains \tcode{decltype(auto)}, the program is ill-formed. The adjusted function parameters of an abbreviated function template are derived from the \grammarterm{parameter-declaration-clause} by replacing each occurrence of a placeholder with the name of the corresponding invented \grammarterm{template-parameter}. \begin{example} \begin{codeblock} template concept C1 = /* ... */; template concept C2 = /* ... */; template concept C3 = /* ... */; void g1(const C1 auto*, C2 auto&); void g2(C1 auto&...); void g3(C3 auto...); void g4(C3 auto); \end{codeblock} The declarations above are functionally equivalent (but not equivalent) to their respective declarations below: \begin{codeblock} template void g1(const T*, U&); template void g2(Ts&...); template void g3(Ts...); template void g4(T); \end{codeblock} Abbreviated function templates can be specialized like all function templates. \begin{codeblock} template<> void g1(const int*, const double&); // OK, specialization of \tcode{g1} \end{codeblock} \end{example} \pnum An abbreviated function template can have a \grammarterm{template-head}. The invented \grammarterm{template-parameter}{s} are appended to the \grammarterm{template-parameter-list} after the explicitly declared \grammarterm{template-parameter}{s}. \begin{example} \begin{codeblock} template concept C = /* ... */; template void g(T x, U y, C auto z); \end{codeblock} This is functionally equivalent to each of the following two declarations. \begin{codeblock} template void g(T x, U y, W z); template requires C && C void g(T x, U y, W z); \end{codeblock} \end{example} \pnum A function declaration at block scope shall not declare an abbreviated function template. \pnum A \grammarterm{declarator-id} or \grammarterm{abstract-declarator} containing an ellipsis shall only be used in a \grammarterm{parameter-declaration}. When it is part of a \grammarterm{parameter-declaration-clause}, the \grammarterm{parameter-declaration} declares a function parameter pack\iref{temp.variadic}. Otherwise, the \grammarterm{parameter-declaration} is part of a \grammarterm{template-parameter-list} and declares a template parameter pack; see~\ref{temp.param}. A function parameter pack is a pack expansion\iref{temp.variadic}. \begin{example} \begin{codeblock} template void f(T (* ...t)(int, int)); int add(int, int); float subtract(int, int); void g() { f(add, subtract); } \end{codeblock} \end{example} \pnum There is a syntactic ambiguity when an ellipsis occurs at the end of a \grammarterm{parameter-declaration-clause} without a preceding comma. In this case, the ellipsis is parsed as part of the \grammarterm{abstract-declarator} if the type of the parameter either names a template parameter pack that has not been expanded or contains \keyword{auto}; otherwise, it is parsed as part of the \grammarterm{parameter-declaration-clause}. \begin{footnote} One can explicitly disambiguate the parse either by introducing a comma (so the ellipsis will be parsed as part of the \grammarterm{parameter-declaration-clause}) or by introducing a name for the parameter (so the ellipsis will be parsed as part of the \grammarterm{declarator-id}). \end{footnote} \indextext{declarator!function|)} \rSec3[dcl.fct.default]{Default arguments}% \indextext{declaration!default argument|(} \pnum If an \grammarterm{initializer-clause}{} is specified in a \grammarterm{parameter-declaration}{} this \grammarterm{initializer-clause}{} is used as a default argument. \begin{note} Default arguments will be used in calls where trailing arguments are missing\iref{expr.call}. \end{note} \pnum \indextext{argument!example of default}% \begin{example} The declaration \begin{codeblock} void point(int = 3, int = 4); \end{codeblock} declares a function that can be called with zero, one, or two arguments of type \tcode{int}. It can be called in any of these ways: \begin{codeblock} point(1,2); point(1); point(); \end{codeblock} The last two calls are equivalent to \tcode{point(1,4)} and \tcode{point(3,4)}, respectively. \end{example} \pnum A default argument shall be specified only in the \grammarterm{parameter-declaration-clause} of a function declaration or \grammarterm{lambda-declarator} or in a \grammarterm{template-parameter}\iref{temp.param}; in the latter case, the \grammarterm{initializer-clause} shall be an \grammarterm{assignment-expression}. A default argument shall not be specified for a template parameter pack or a function parameter pack. If it is specified in a \grammarterm{parameter-declaration-clause}, it shall not occur within a \grammarterm{declarator} or \grammarterm{abstract-declarator} of a \grammarterm{parameter-declaration}. \begin{footnote} This means that default arguments cannot appear, for example, in declarations of pointers to functions, references to functions, or \tcode{typedef} declarations. \end{footnote} \pnum For non-template functions, default arguments can be added in later declarations of a function that inhabit the same scope. Declarations that inhabit different scopes have completely distinct sets of default arguments. That is, declarations in inner scopes do not acquire default arguments from declarations in outer scopes, and vice versa. 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. \begin{note} A default argument cannot be redefined by a later declaration (not even to the same value)\iref{basic.def.odr}. \end{note} \begin{example} \begin{codeblock} void g(int = 0, ...); // OK, ellipsis is not a parameter so it can follow // a parameter with a default argument void f(int, int); void f(int, int = 7); void h() { f(3); // OK, calls \tcode{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 arguments void f(int, int = 5); // OK f(4); // OK, calls \tcode{f(4, 5);} void f(int, int = 5); // error: cannot redefine, even to same value } void n() { f(6); // OK, calls \tcode{f(6, 7)} } template struct C { void f(int n = 0, T...); }; C c; // OK, instantiates declaration \tcode{void C::f(int n = 0, int)} \end{codeblock} \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. 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. \pnum \indextext{argument!type checking of default}% \indextext{argument!binding of default}% \indextext{argument!evaluation of default}% 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\iref{dcl.init}. 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\iref{expr.const} that is a potentially-evaluated subexpression\iref{intro.execution} of the \grammarterm{initializer-clause} in a \grammarterm{parameter-declaration} is neither evaluated nor checked for whether it is a constant expression at that point. Name lookup and checking of semantic constraints for default arguments of templated functions are performed as described in~\ref{temp.inst}. \begin{example} In the following code, \indextext{argument!example of default}% \tcode{g} will be called with the value \tcode{f(2)}: \begin{codeblock} int a = 1; int f(int); int g(int x = f(a)); // default argument: \tcode{f(::a)} void h() { a = 2; { int a = 3; g(); // \tcode{g(f(::a))} } } \end{codeblock} \end{example} \begin{note} A default argument is a complete-class context\iref{class.mem}. Access checking applies to names in default arguments as described in \ref{class.access}. \end{note} \pnum Except for member functions of class templates, 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\iref{class.default.ctor}, copy or move constructor\iref{class.copy.ctor}, or copy or move assignment operator\iref{class.copy.assign} is so declared. Default arguments for a member function of a class template shall be specified on the initial declaration of the member function within the class template. \begin{example} \begin{codeblock} 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 scope void C::g(int i = 88, int j) {} // in this translation unit, \tcode{C::g} can be called with no arguments \end{codeblock} \end{example} \pnum \begin{note} A local variable cannot be odr-used\iref{term.odr.use} in a default argument. \end{note} \begin{example} \begin{codeblock} void f() { int i; extern void g(int x = i); // error extern void h(int x = sizeof(i)); // OK // ... } \end{codeblock} \end{example} \pnum \begin{note} The keyword \keyword{this} cannot appear in a default argument of a member function; see~\ref{expr.prim.this}. \begin{example} \begin{codeblock} class A { void f(A* p = this) { } // error }; \end{codeblock} \end{example} \end{note} \pnum \indextext{argument!evaluation of default}% A default argument is evaluated each time the function is called with no argument for the corresponding parameter. \indextext{argument!scope of default}% A parameter shall not appear as a potentially-evaluated expression in a default argument. \indextext{argument and name hiding!default}% \begin{note} Parameters of a function declared before a default argument are in scope and can hide namespace and class member names. \end{note} \begin{example} \begin{codeblock} int a; int f(int a, int b = a); // error: parameter \tcode{a} used as default argument typedef int I; int g(float I, int b = I(2)); // error: parameter \tcode{I} found int h(int a, int b = sizeof(a)); // OK, unevaluated operand\iref{term.unevaluated.operand} \end{codeblock} \end{example} A non-static member shall not appear in a default argument unless it appears as the \grammarterm{id-expression} of a class member access expression\iref{expr.ref} or unless it is used to form a pointer to member\iref{expr.unary.op}. \begin{example} The declaration of \tcode{X::mem1()} in the following example is ill-formed because no object is supplied for the non-static member \tcode{X::a} used as an initializer. \begin{codeblock} int b; class X { int a; int mem1(int i = a); // error: non-static member \tcode{a} used as default argument int mem2(int i = b); // OK; use \tcode{X::b} static int b; }; \end{codeblock} The declaration of \tcode{X::mem2()} is meaningful, however, since no object is needed to access the static member \tcode{X::b}. Classes, objects, and members are described in \ref{class}. \end{example} A default argument is not part of the type of a function. \begin{example} \begin{codeblock} int f(int = 0); void h() { int j = f(1); int k = f(); // OK, means \tcode{f(0)} } int (*p1)(int) = &f; int (*p2)() = &f; // error: type mismatch \end{codeblock} \end{example} When an overload set contains a declaration of a function that inhabits a scope $S$, any default argument associated with any reachable declaration that inhabits $S$ is available to the call. \begin{note} The candidate might have been found through a \grammarterm{using-declarator} from which the declaration that provides the default argument is not reachable. \end{note} \pnum \indextext{argument and virtual function!default}% A virtual function call\iref{class.virtual} uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. An overriding function in a derived class does not acquire default arguments from the function it overrides. \begin{example} \begin{codeblock} 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 \tcode{pa->B::f(7)} pb->f(); // error: wrong number of arguments for \tcode{B::f()} } \end{codeblock} \end{example} \indextext{declaration!default argument|)}% \indextext{declarator!meaning of|)} \rSec1[dcl.init]{Initializers}% \rSec2[dcl.init.general]{General}% \indextext{initialization|(} \pnum The process of initialization described in \ref{dcl.init} applies to all initializations regardless of syntactic context, including the initialization of a function parameter\iref{expr.call}, the initialization of a return value\iref{stmt.return}, or when an initializer follows a declarator. \begin{bnf} \nontermdef{initializer}\br brace-or-equal-initializer\br \terminal{(} expression-list \terminal{)} \end{bnf} \begin{bnf} \nontermdef{brace-or-equal-initializer}\br \terminal{=} initializer-clause\br braced-init-list \end{bnf} \begin{bnf} \nontermdef{initializer-clause}\br assignment-expression\br braced-init-list \end{bnf} \begin{bnf} \nontermdef{braced-init-list}\br \terminal{\{} initializer-list \opt{\terminal{,}} \terminal{\}}\br \terminal{\{} designated-initializer-list \opt{\terminal{,}} \terminal{\}}\br \terminal{\{} \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{initializer-list}\br initializer-clause \opt{\terminal{...}}\br initializer-list \terminal{,} initializer-clause \opt{\terminal{...}} \end{bnf} \begin{bnf} \nontermdef{designated-initializer-list}\br designated-initializer-clause\br designated-initializer-list \terminal{,} designated-initializer-clause \end{bnf} \begin{bnf} \nontermdef{designated-initializer-clause}\br designator brace-or-equal-initializer \end{bnf} \begin{bnf} \nontermdef{designator}\br \terminal{.} identifier \end{bnf} \begin{bnf} \nontermdef{expr-or-braced-init-list}\br expression\br braced-init-list \end{bnf} \begin{note} The rules in \ref{dcl.init} apply even if the grammar permits only the \grammarterm{brace-or-equal-initializer} form of \grammarterm{initializer} in a given context. \end{note} \pnum Except for objects declared with the \keyword{constexpr} specifier, for which see~\ref{dcl.constexpr}, an \grammarterm{initializer} in the definition of a variable can consist of arbitrary expressions involving literals and previously declared variables and functions, regardless of the variable's storage duration. \begin{example} \begin{codeblock} int f(int); int a = 2; int b = f(a); int c(b); \end{codeblock} \end{example} \pnum \begin{note} Default arguments are more restricted; see~\ref{dcl.fct.default}. \end{note} \pnum \begin{note} The order of initialization of variables with static storage duration is described in~\ref{basic.start} and~\ref{stmt.dcl}. \end{note} \pnum A declaration $D$ of a variable with linkage shall not have an \grammarterm{initializer} if $D$ inhabits a block scope. \pnum \indextext{initialization!default}% \indextext{variable!indeterminate uninitialized}% \indextext{initialization!zero-initialization}% To \defnx{zero-initialize}{zero-initialization} an object or reference of type \tcode{T} means: \begin{itemize} \item if \tcode{T} is a scalar type\iref{term.scalar.type}, the object is initialized to the value obtained by converting the integer literal \tcode{0} (zero) to \tcode{T}; \begin{footnote} As specified in~\ref{conv.ptr}, converting an integer literal whose value is \tcode{0} to a pointer type results in a null pointer value. \end{footnote} \item if \tcode{T} is a (possibly cv-qualified) non-union class type, its padding bits\iref{term.padding.bits} are initialized to zero bits and each non-static data member, each non-virtual base class subobject, and, if the object is not a base class subobject, each virtual base class subobject is zero-initialized; \item if \tcode{T} is a (possibly cv-qualified) union type, its padding bits\iref{term.padding.bits} are initialized to zero bits and the object's first non-static named data member is zero-initialized; \item if \tcode{T} is an array type, each element is zero-initialized; \item if \tcode{T} is a reference type, no initialization is performed. \end{itemize} \pnum To \defnx{default-initialize}{default-initialization} an object of type \tcode{T} means: \begin{itemize} \item If \tcode{T} is a (possibly cv-qualified) class type\iref{class}, constructors are considered. The applicable constructors are enumerated\iref{over.match.ctor}, and the best one for the \grammarterm{initializer} \tcode{()} is chosen through overload resolution\iref{over.match}. The constructor thus selected is called, with an empty argument list, to initialize the object. \item If \tcode{T} is an array type, each element is default-initialized. \item Otherwise, no initialization is performed. \end{itemize} \pnum A class type \tcode{T} is \defn{const-default-constructible} if default-initialization of \tcode{T} would invoke a user-provided constructor of \tcode{T} (not inherited from a base class) or if \begin{itemize} \item each direct non-variant non-static data member \tcode{M} of \tcode{T} has a default member initializer or, if \tcode{M} is of class type \tcode{X} (or array thereof), \tcode{X} is const-default-constructible, \item if \tcode{T} is a union with at least one non-static data member, exactly one variant member has a default member initializer, \item if \tcode{T} is not a union, for each anonymous union member with at least one non-static data member (if any), exactly one non-static data member has a default member initializer, and \item each potentially constructed base class of \tcode{T} is const-default-constructible. \end{itemize} If a program calls for the default-initialization of an object of a const-qualified type \tcode{T}, \tcode{T} shall be a const-default-constructible class type or array thereof. \pnum To \defnx{value-initialize}{value-initialization} an object of type \tcode{T} means: \begin{itemize} \item if \tcode{T} is a (possibly cv-qualified) class type\iref{class}, then \begin{itemize} \item if \tcode{T} has either no default constructor\iref{class.default.ctor} or a default constructor that is user-provided or deleted, then the object is default-initialized; \item otherwise, the object is zero-initialized and the semantic constraints for default-initialization are checked, and if \tcode{T} has a non-trivial default constructor, the object is default-initialized; \end{itemize} \item if \tcode{T} is an array type, then each element is value-initialized; \item otherwise, the object is zero-initialized. \end{itemize} \pnum A program that calls for default-initialization or value-initialization of an entity of reference type is ill-formed. \pnum \begin{note} For every object of static storage duration, static initialization\iref{basic.start.static} is performed at program startup before any other initialization takes place. In some cases, additional initialization is done later. \end{note} \pnum If no initializer is specified for an object, the object is default-initialized. \pnum If the entity being initialized does not have class type, the \grammarterm{expression-list} in a parenthesized initializer shall be a single expression. \pnum \indextext{initialization!copy}% \indextext{initialization!direct}% The initialization that occurs in the \tcode{=} form of a \grammarterm{brace-or-equal-initializer} or \grammarterm{condition}\iref{stmt.select}, as well as in argument passing, function return, throwing an exception\iref{except.throw}, handling an exception\iref{except.handle}, and aggregate member initialization other than by a \grammarterm{designated-initializer-clause}\iref{dcl.init.aggr}, is called \defn{copy-initialization}. \begin{note} Copy-initialization can invoke a move\iref{class.copy.ctor}. \end{note} \pnum The initialization that occurs \begin{itemize} \item for an \grammarterm{initializer} that is a parenthesized \grammarterm{expression-list} or a \grammarterm{braced-init-list}, \item for a \grammarterm{new-initializer}\iref{expr.new}, \item in a \keyword{static_cast} expression\iref{expr.static.cast}, \item in a functional notation type conversion\iref{expr.type.conv}, and \item in the \grammarterm{braced-init-list} form of a \grammarterm{condition} \end{itemize} is called \defn{direct-initialization}. \pnum The semantics of initializers are as follows. The \indextext{type!destination}% \term{destination type} is the type of the object or reference being initialized and the \term{source type} is the type of the initializer expression. If the initializer is not a single (possibly parenthesized) expression, the source type is not defined. \begin{itemize} \item If the initializer is a (non-parenthesized) \grammarterm{braced-init-list} or is \tcode{=} \grammarterm{braced-init-list}, the object or reference is list-initialized\iref{dcl.init.list}. \item If the destination type is a reference type, see~\ref{dcl.init.ref}. \item If the destination type is an array of characters, an array of \keyword{char8_t}, an array of \keyword{char16_t}, an array of \keyword{char32_t}, or an array of \keyword{wchar_t}, and the initializer is a \grammarterm{string-literal}, see~\ref{dcl.init.string}. \item If the initializer is \tcode{()}, the object is value-initialized. \indextext{ambiguity!function declaration}% \begin{note} Since \tcode{()} is not permitted by the syntax for \grammarterm{initializer}, \begin{codeblock} X a(); \end{codeblock} is not the declaration of an object of class \tcode{X}, but the declaration of a function taking no arguments and returning an \tcode{X}. The form \tcode{()} is permitted in certain other initialization contexts\iref{expr.new, expr.type.conv,class.base.init}. \end{note} \item Otherwise, if the destination type is an array, the object is initialized as follows. Let $x_1$, $\dotsc$, $x_k$ be the elements of the \grammarterm{expression-list}. If the destination type is an array of unknown bound, it is defined as having $k$ elements. Let $n$ denote the array size after this potential adjustment. If $k$ is greater than $n$, the program is ill-formed. Otherwise, the $i^\text{th}$ array element is copy-initialized with $x_i$ for each $1 \leq i \leq k$, and value-initialized for each $k < i \leq n$. For each $1 \leq i < j \leq n$, every value computation and side effect associated with the initialization of the $i^\text{th}$ element of the array is sequenced before those associated with the initialization of the $j^\text{th}$ element. \item Otherwise, if the destination type is a (possibly cv-qualified) class type: \begin{itemize} \item If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object. \begin{example} \tcode{T x = T(T(T()));} value-initializes \tcode{x}. \end{example} \item Otherwise, if the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, constructors are considered. The applicable constructors are enumerated\iref{over.match.ctor}, and the best one is chosen through overload resolution\iref{over.match}. Then: \begin{itemize} \item If overload resolution is successful, the selected constructor is called to initialize the object, with the initializer expression or \grammarterm{expression-list} as its argument(s). \item Otherwise, if no constructor is viable, the destination type is an aggregate class, and the initializer is a parenthesized \grammarterm{expression-list}, the object is initialized as follows. Let $e_1$, $\dotsc$, $e_n$ be the elements of the aggregate\iref{dcl.init.aggr}. Let $x_1$, $\dotsc$, $x_k$ be the elements of the \grammarterm{expression-list}. If $k$ is greater than $n$, the program is ill-formed. The element $e_i$ is copy-initialized with $x_i$ for $1 \leq i \leq k$. The remaining elements are initialized with their default member initializers, if any, and otherwise are value-initialized. For each $1 \leq i < j \leq n$, every value computation and side effect associated with the initialization of $e_i$ is sequenced before those associated with the initialization of $e_j$. \begin{note} By contrast with direct-list-initialization, narrowing conversions\iref{dcl.init.list} are permitted, designators are not permitted, a temporary object bound to a reference does not have its lifetime extended\iref{class.temporary}, and there is no brace elision. \begin{example} \begin{codeblock} struct A { int a; int&& r; }; int f(); int n = 10; A a1{1, f()}; // OK, lifetime is extended A a2(1, f()); // well-formed, but dangling reference A a3{1.0, 1}; // error: narrowing conversion A a4(1.0, 1); // well-formed, but dangling reference A a5(1.0, std::move(n)); // OK \end{codeblock} \end{example} \end{note} \item Otherwise, the initialization is ill-formed. \end{itemize} \item Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversions that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated as described in~\ref{over.match.copy}, and the best one is chosen through overload resolution\iref{over.match}. If the conversion cannot be done or is ambiguous, the initialization is ill-formed. The function selected is called with the initializer expression as its argument; if the function is a constructor, the call is a prvalue of the cv-unqualified version of the destination type whose result object is initialized by the constructor. The call is used to direct-initialize, according to the rules above, the object that is the destination of the copy-initialization. \end{itemize} \item Otherwise, if the source type is a (possibly cv-qualified) class type, conversion functions are considered. The applicable conversion functions are enumerated\iref{over.match.conv}, and the best one is chosen through overload resolution\iref{over.match}. The user-defined conversion so selected is called to convert the initializer expression into the object being initialized. If the conversion cannot be done or is ambiguous, the initialization is ill-formed. \item Otherwise, if the initialization is direct-initialization, the source type is \tcode{std::nullptr_t}, and the destination type is \tcode{bool}, the initial value of the object being initialized is \tcode{false}. \item Otherwise, the initial value of the object being initialized is the (possibly converted) value of the initializer expression. A standard conversion sequence\iref{conv} will be used, if necessary, to convert the initializer expression to the cv-unqualified version of the destination type; no user-defined conversions are considered. If the conversion cannot be done, the initialization is ill-formed. When initializing a bit-field with a value that it cannot represent, the resulting value of the bit-field is \impldefplain{value of bit-field that cannot represent!initializer}. \indextext{initialization!\idxcode{const}}% \begin{note} An expression of type ``\cvqual{cv1} \tcode{T}'' can initialize an object of type ``\cvqual{cv2} \tcode{T}'' independently of the cv-qualifiers \cvqual{cv1} and \cvqual{cv2}. \begin{codeblock} int a; const int b = a; int c = b; \end{codeblock} \end{note} \end{itemize} \pnum An immediate invocation\iref{expr.const} that is not evaluated where it appears\iref{dcl.fct.default,class.mem.general} is evaluated and checked for whether it is a constant expression at the point where the enclosing \grammarterm{initializer} is used in a function call, a constructor definition, or an aggregate initialization. \pnum An \grammarterm{initializer-clause} followed by an ellipsis is a pack expansion\iref{temp.variadic}. \pnum Initialization includes the evaluation of all subexpressions of each \grammarterm{initializer-clause} of the initializer (possibly nested within \grammarterm{braced-init-list}{s}) and the creation of any temporary objects for function arguments or return values\iref{class.temporary}. \pnum If the initializer is a parenthesized \grammarterm{expression-list}, the expressions are evaluated in the order specified for function calls\iref{expr.call}. \pnum The same \grammarterm{identifier} shall not appear in multiple \grammarterm{designator}{s} of a \grammarterm{designated-initializer-list}. \pnum An object whose initialization has completed is deemed to be constructed, even if the object is of non-class type or no constructor of the object's class is invoked for the initialization. \begin{note} Such an object might have been value-initialized or initialized by aggregate initialization\iref{dcl.init.aggr} or by an inherited constructor\iref{class.inhctor.init}. \end{note} Destroying an object of class type invokes the destructor of the class. Destroying a scalar type has no effect other than ending the lifetime of the object\iref{basic.life}. Destroying an array destroys each element in reverse subscript order. \pnum A declaration that specifies the initialization of a variable, whether from an explicit initializer or by default-initialization, is called the \defn{initializing declaration} of that variable. \begin{note} In most cases this is the defining declaration\iref{basic.def} of the variable, but the initializing declaration of a non-inline static data member\iref{class.static.data} can be the declaration within the class definition and not the definition (if any) outside it. \end{note} \rSec2[dcl.init.aggr]{Aggregates}% \indextext{aggregate}% \indextext{initialization!aggregate}% \indextext{aggregate initialization}% \indextext{initialization!array}% \indextext{initialization!class object}% \indextext{class object initialization|see{constructor}}% \indextext{\idxcode{\{\}}!initializer list} \pnum An \defn{aggregate} is an array or a class\iref{class} with \begin{itemize} \item no user-declared or inherited constructors\iref{class.ctor}, \item no private or protected direct non-static data members\iref{class.access}, \item no private or protected direct base classes\iref{class.access.base}, and \item no virtual functions\iref{class.virtual} or virtual base classes\iref{class.mi}. \end{itemize} \begin{note} Aggregate initialization does not allow accessing protected and private base class' members or constructors. \end{note} \pnum The \defnx{elements}{aggregate!elements} of an aggregate are: \begin{itemize} \item for an array, the array elements in increasing subscript order, or \item for a class, the direct base classes in declaration order, followed by the direct non-static data members\iref{class.mem} that are not members of an anonymous union, in declaration order. \end{itemize} \pnum When an aggregate is initialized by an initializer list as specified in~\ref{dcl.init.list}, the elements of the initializer list are taken as initializers for the elements of the aggregate. The \defnx{explicitly initialized elements}{explicitly initialized elements!aggregate} of the aggregate are determined as follows: \begin{itemize} \item If the initializer list is a brace-enclosed \grammarterm{designated-initializer-list}, the aggregate shall be of class type, the \grammarterm{identifier} in each \grammarterm{designator} shall name a direct non-static data member of the class, and the explicitly initialized elements of the aggregate are the elements that are, or contain, those members. \item If the initializer list is a brace-enclosed \grammarterm{initializer-list}, the explicitly initialized elements of the aggregate are the first $n$ elements of the aggregate, where $n$ is the number of elements in the initializer list. \item Otherwise, the initializer list must be \tcode{\{\}}, and there are no explicitly initialized elements. \end{itemize} \pnum For each explicitly initialized element: \begin{itemize} \item If the element is an anonymous union member and the initializer list is a brace-enclosed \grammarterm{designated-initializer-list}, the element is initialized by the \grammarterm{braced-init-list} \tcode{\{ }\placeholder{D}\tcode{ \}}, where \placeholder{D} is the \grammarterm{designated-initializer-clause} naming a member of the anonymous union member. There shall be only one such \grammarterm{designated-initializer-clause}. \begin{example} \begin{codeblock} struct C { union { int a; const char* p; }; int x; } c = { .a = 1, .x = 3 }; \end{codeblock} initializes \tcode{c.a} with 1 and \tcode{c.x} with 3. \end{example} \item Otherwise, the element is copy-initialized from the corresponding \grammarterm{initializer-clause} or is initialized with the \grammarterm{brace-or-equal-initializer} of the corresponding \grammarterm{designated-initializer-clause}. If that initializer is of the form \grammarterm{assignment-expression} or \tcode{= }\grammarterm{assignment-expression} and a narrowing conversion\iref{dcl.init.list} is required to convert the expression, the program is ill-formed. \begin{note} If the initialization is by \grammarterm{designated-initializer-clause}, its form determines whether copy-initialization or direct-initialization is performed. \end{note} \begin{note} If an initializer is itself an initializer list, the element is list-initialized, which will result in a recursive application of the rules in this subclause if the element is an aggregate. \end{note} \begin{example} \begin{codeblock} struct A { int x; struct B { int i; int j; } b; } a = { 1, { 2, 3 } }; \end{codeblock} initializes \tcode{a.x} with 1, \tcode{a.b.i} with 2, \tcode{a.b.j} with 3. \begin{codeblock} struct base1 { int b1, b2 = 42; }; struct base2 { base2() { b3 = 42; } int b3; }; struct derived : base1, base2 { int d; }; derived d1{{1, 2}, {}, 4}; derived d2{{}, {}, 4}; \end{codeblock} initializes \tcode{d1.b1} with 1, \tcode{d1.b2} with 2, \tcode{d1.b3} with 42, \tcode{d1.d} with 4, and \tcode{d2.b1} with 0, \tcode{d2.b2} with 42, \tcode{d2.b3} with 42, \tcode{d2.d} with 4. \end{example} \end{itemize} \pnum For a non-union aggregate, each element that is not an explicitly initialized element is initialized as follows: \begin{itemize} \item If the element has a default member initializer\iref{class.mem}, the element is initialized from that initializer. \item Otherwise, if the element is not a reference, the element is copy-initialized from an empty initializer list\iref{dcl.init.list}. \item Otherwise, the program is ill-formed. \end{itemize} If the aggregate is a union and the initializer list is empty, then \begin{itemize} \item if any variant member has a default member initializer, that member is initialized from its default member initializer; \item otherwise, the first member of the union (if any) is copy-initialized from an empty initializer list. \end{itemize} \pnum \begin{example} \begin{codeblock} struct S { int a; const char* b; int c; int d = b[a]; }; S ss = { 1, "asdf" }; \end{codeblock} initializes \tcode{ss.a} with 1, \tcode{ss.b} with \tcode{"asdf"}, \tcode{ss.c} with the value of an expression of the form \tcode{int\{\}} (that is, \tcode{0}), and \tcode{ss.d} with the value of \tcode{ss.b[ss.a]} (that is, \tcode{'s'}), and in \begin{codeblock} struct X { int i, j, k = 42; }; X a[] = { 1, 2, 3, 4, 5, 6 }; X b[2] = { { 1, 2, 3 }, { 4, 5, 6 } }; \end{codeblock} \tcode{a} and \tcode{b} have the same value \begin{codeblock} struct A { string a; int b = 42; int c = -1; }; \end{codeblock} \tcode{A\{.c=21\}} has the following steps: \begin{itemize} \item Initialize \tcode{a} with \tcode{\{\}} \item Initialize \tcode{b} with \tcode{= 42} \item Initialize \tcode{c} with \tcode{= 21} \end{itemize} \end{example} \pnum The initializations of the elements of the aggregate are evaluated in the element order. That is, all value computations and side effects associated with a given element are sequenced before those of any element that follows it in order. \pnum An aggregate that is a class can also be initialized with a single expression not enclosed in braces, as described in~\ref{dcl.init}. \pnum The destructor for each element of class type is potentially invoked\iref{class.dtor} from the context where the aggregate initialization occurs. \begin{note} This provision ensures that destructors can be called for fully-constructed subobjects in case an exception is thrown\iref{except.ctor}. \end{note} \pnum An array of unknown bound initialized with a brace-enclosed \grammarterm{initializer-list} containing \tcode{n} \grammarterm{initializer-clause}{s} is defined as having \tcode{n} elements\iref{dcl.array}. \begin{example} \begin{codeblock} int x[] = { 1, 3, 5 }; \end{codeblock} declares and initializes \tcode{x} as a one-dimensional array that has three elements since no size was specified and there are three initializers. \end{example} An array of unknown bound shall not be initialized with an empty \grammarterm{braced-init-list} \tcode{\{\}}. \begin{footnote} The syntax provides for empty \grammarterm{braced-init-list}{s}, but nonetheless \Cpp{} does not have zero length arrays. \end{footnote} \begin{note} A default member initializer does not determine the bound for a member array of unknown bound. Since the default member initializer is ignored if a suitable \grammarterm{mem-initializer} is present\iref{class.base.init}, the default member initializer is not considered to initialize the array of unknown bound. \begin{example} \begin{codeblock} struct S { int y[] = { 0 }; // error: non-static data member of incomplete type }; \end{codeblock} \end{example} \end{note} \pnum \begin{note} Static data members, non-static data members of anonymous union members, and unnamed bit-fields are not considered elements of the aggregate. \begin{example} \begin{codeblock} struct A { int i; static int s; int j; int :17; int k; } a = { 1, 2, 3 }; \end{codeblock} Here, the second initializer 2 initializes \tcode{a.j} and not the static data member \tcode{A::s}, and the third initializer 3 initializes \tcode{a.k} and not the unnamed bit-field before it. \end{example} \end{note} \pnum An \grammarterm{initializer-list} is ill-formed if the number of \grammarterm{initializer-clause}{s} exceeds the number of elements of the aggregate. \begin{example} \begin{codeblock} char cv[4] = { 'a', 's', 'd', 'f', 0 }; // error \end{codeblock} is ill-formed. \end{example} \pnum If a member has a default member initializer and a potentially-evaluated subexpression thereof is an aggregate initialization that would use that default member initializer, the program is ill-formed. \begin{example} \begin{codeblock} struct A; extern A a; struct A { const A& a1 { A{a,a} }; // OK const A& a2 { A{} }; // error }; A a{a,a}; // OK struct B { int n = B{}.n; // error }; \end{codeblock} \end{example} \pnum If an aggregate class \tcode{C} contains a subaggregate element \tcode{e} with no elements, the \grammarterm{initializer-clause} for \tcode{e} shall not be omitted from an \grammarterm{initializer-list} for an object of type \tcode{C} unless the \grammarterm{initializer-clause}{s} for all elements of \tcode{C} following \tcode{e} are also omitted. \begin{example} \begin{codeblock} struct S { } s; struct A { S s1; int i1; S s2; int i2; S s3; int i3; } a = { { }, // Required initialization 0, s, // Required initialization 0 }; // Initialization not required for \tcode{A::s3} because \tcode{A::i3} is also not initialized \end{codeblock} \end{example} \pnum When initializing a multidimensional array, the \grammarterm{initializer-clause}{s} initialize the elements with the last (rightmost) index of the array varying the fastest\iref{dcl.array}. \begin{example} \begin{codeblock} int x[2][2] = { 3, 1, 4, 2 }; \end{codeblock} initializes \tcode{x[0][0]} to \tcode{3}, \tcode{x[0][1]} to \tcode{1}, \tcode{x[1][0]} to \tcode{4}, and \tcode{x[1][1]} to \tcode{2}. On the other hand, \begin{codeblock} float y[4][3] = { { 1 }, { 2 }, { 3 }, { 4 } }; \end{codeblock} initializes the first column of \tcode{y} (regarded as a two-dimensional array) and leaves the rest zero. \end{example} \pnum Braces can be elided in an \grammarterm{initializer-list} as follows. If the \grammarterm{initializer-list} begins with a left brace, then the succeeding comma-separated list of \grammarterm{initializer-clause}{s} initializes the elements of a subaggregate; it is erroneous for there to be more \grammarterm{initializer-clause}{s} than elements. If, however, the \grammarterm{initializer-list} for a subaggregate does not begin with a left brace, then only enough \grammarterm{initializer-clause}{s} from the list are taken to initialize the elements of the subaggregate; any remaining \grammarterm{initializer-clause}{s} are left to initialize the next element of the aggregate of which the current subaggregate is an element. \begin{example} \begin{codeblock} float y[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 }, }; \end{codeblock} is a completely-braced initialization: 1, 3, and 5 initialize the first row of the array \tcode{y[0]}, namely \tcode{y[0][0]}, \tcode{y[0][1]}, and \tcode{y[0][2]}. Likewise the next two lines initialize \tcode{y[1]} and \tcode{y[2]}. The initializer ends early and therefore \tcode{y[3]}s elements are initialized as if explicitly initialized with an expression of the form \tcode{float()}, that is, are initialized with \tcode{0.0}. In the following example, braces in the \grammarterm{initializer-list} are elided; however the \grammarterm{initializer-list} has the same effect as the completely-braced \grammarterm{initializer-list} of the above example, \begin{codeblock} float y[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 }; \end{codeblock} The initializer for \tcode{y} begins with a left brace, but the one for \tcode{y[0]} does not, therefore three elements from the list are used. Likewise the next three are taken successively for \tcode{y[1]} and \tcode{y[2]}. \end{example} \pnum All implicit type conversions\iref{conv} are considered when initializing the element with an \grammarterm{assignment-expression}. If the \grammarterm{assignment-expression} can initialize an element, the element is initialized. Otherwise, if the element is itself a subaggregate, brace elision is assumed and the \grammarterm{assignment-expression} is considered for the initialization of the first element of the subaggregate. \begin{note} As specified above, brace elision cannot apply to subaggregates with no elements; an \grammarterm{initializer-clause} for the entire subobject is required. \end{note} \begin{example} \begin{codeblock} struct A { int i; operator int(); }; struct B { A a1, a2; int z; }; A a; B b = { 4, a, a }; \end{codeblock} Braces are elided around the \grammarterm{initializer-clause} for \tcode{b.a1.i}. \tcode{b.a1.i} is initialized with 4, \tcode{b.a2} is initialized with \tcode{a}, \tcode{b.z} is initialized with whatever \tcode{a.operator int()} returns. \end{example} \pnum \indextext{initialization!array of class objects}% \begin{note} An aggregate array or an aggregate class can contain elements of a class type with a user-declared constructor\iref{class.ctor}. Initialization of these aggregate objects is described in~\ref{class.expl.init}. \end{note} \pnum \begin{note} Whether the initialization of aggregates with static storage duration is static or dynamic is specified in~\ref{basic.start.static}, \ref{basic.start.dynamic}, and~\ref{stmt.dcl}. \end{note} \pnum \indextext{initialization!\idxcode{union}}% When a union is initialized with an initializer list, there shall not be more than one explicitly initialized element. \begin{example} \begin{codeblock} union u { int a; const char* b; }; u a = { 1 }; u b = a; u c = 1; // error u d = { 0, "asdf" }; // error u e = { "asdf" }; // error u f = { .b = "asdf" }; u g = { .a = 1, .b = "asdf" }; // error \end{codeblock} \end{example} \pnum \begin{note} As described above, the braces around the \grammarterm{initializer-clause} for a union member can be omitted if the union is a member of another aggregate. \end{note} \rSec2[dcl.init.string]{Character arrays}% \indextext{initialization!character array} \pnum \indextext{UTF-8}% \indextext{UTF-16}% \indextext{UTF-32}% An array of ordinary character type\iref{basic.fundamental}, \keyword{char8_t} array, \keyword{char16_t} array, \keyword{char32_t} array, or \keyword{wchar_t} array may be initialized by an ordinary string literal, UTF-8 string literal, UTF-16 string literal, UTF-32 string literal, or wide string literal, respectively, or by an appropriately-typed \grammarterm{string-literal} enclosed in braces\iref{lex.string}. Additionally, an array of \keyword{char} or \tcode{\keyword{unsigned} \keyword{char}} may be initialized by a UTF-8 string literal, or by such a string literal enclosed in braces. \indextext{initialization!character array}% Successive characters of the value of the \grammarterm{string-literal} initialize the elements of the array, with an integral conversion\iref{conv.integral} if necessary for the source and destination value. \begin{example} \begin{codeblock} char msg[] = "Syntax error on line %s\n"; \end{codeblock} shows a character array whose members are initialized with a \grammarterm{string-literal}. Note that because \tcode{'\textbackslash n'} is a single character and because a trailing \tcode{'\textbackslash 0'} is appended, \tcode{sizeof(msg)} is \tcode{25}. \end{example} \pnum There shall not be more initializers than there are array elements. \begin{example} \begin{codeblock} char cv[4] = "asdf"; // error \end{codeblock} is ill-formed since there is no space for the implied trailing \tcode{'\textbackslash 0'}. \end{example} \pnum If there are fewer initializers than there are array elements, each element not explicitly initialized shall be zero-initialized\iref{dcl.init}. \rSec2[dcl.init.ref]{References}% \indextext{initialization!reference} \pnum A variable whose declared type is ``reference to \tcode{T}''\iref{dcl.ref} shall be initialized. \begin{example} \begin{codeblock} int g(int) noexcept; void f() { int i; int& r = i; // \tcode{r} refers to \tcode{i} r = 1; // the value of \tcode{i} becomes \tcode{1} int* p = &r; // \tcode{p} points to \tcode{i} int& rr = r; // \tcode{rr} refers to what \tcode{r} refers to, that is, to \tcode{i} int (&rg)(int) = g; // \tcode{rg} refers to the function \tcode{g} rg(i); // calls function \tcode{g} int a[3]; int (&ra)[3] = a; // \tcode{ra} refers to the array \tcode{a} ra[1] = i; // modifies \tcode{a[1]} } \end{codeblock} \end{example} \pnum A reference cannot be changed to refer to another object after initialization. \indextext{assignment!reference}% \begin{note} Assignment to a reference assigns to the object referred to by the reference\iref{expr.ass}. \end{note} \indextext{argument passing!reference and}% Argument passing\iref{expr.call} \indextext{\idxcode{return}!reference and}% and function value return\iref{stmt.return} are initializations. \pnum The initializer can be omitted for a reference only in a parameter declaration\iref{dcl.fct}, in the declaration of a function return type, in the declaration of a class member within its class definition\iref{class.mem}, and where the \keyword{extern} specifier is explicitly used. \indextext{declaration!extern@\tcode{extern} reference}% \begin{example} \begin{codeblock} int& r1; // error: initializer missing extern int& r2; // OK \end{codeblock} \end{example} \pnum Given types ``\cvqual{cv1} \tcode{T1}'' and ``\cvqual{cv2} \tcode{T2}'', ``\cvqual{cv1} \tcode{T1}'' is \defn{reference-related} to ``\cvqual{cv2} \tcode{T2}'' if \tcode{T1} is similar\iref{conv.qual} to \tcode{T2}, or \tcode{T1} is a base class of \tcode{T2}. ``\cvqual{cv1} \tcode{T1}'' is \defn{reference-compatible} with ``\cvqual{cv2} \tcode{T2}'' if a prvalue of type ``pointer to \cvqual{cv2} \tcode{T2}'' can be converted to the type ``pointer to \cvqual{cv1} \tcode{T1}'' via a standard conversion sequence\iref{conv}. In all cases where the reference-compatible relationship of two types is used to establish the validity of a reference binding and the standard conversion sequence would be ill-formed, a program that necessitates such a binding is ill-formed. \pnum A reference to type ``\cvqual{cv1} \tcode{T1}'' is initialized by an expression of type ``\cvqual{cv2} \tcode{T2}'' as follows:% \indextext{binding!reference} \begin{itemize} \item If the reference is an lvalue reference and the initializer expression \begin{itemize} \item is an lvalue (but is not a bit-field), and ``\cvqual{cv1} \tcode{T1}'' is reference-compatible with ``\cvqual{cv2} \tcode{T2}'', or \item has a class type (i.e., \tcode{T2} is a class type), where \tcode{T1} is not reference-related to \tcode{T2}, and can be converted to an lvalue of type ``\cvqual{cv3} \tcode{T3}'', where ``\cvqual{cv1} \tcode{T1}'' is reference-compatible with ``\cvqual{cv3} \tcode{T3}'' \begin{footnote} This requires a conversion function\iref{class.conv.fct} returning a reference type. \end{footnote} (this conversion is selected by enumerating the applicable conversion functions\iref{over.match.ref} and choosing the best one through overload resolution\iref{over.match}), \end{itemize} then the reference binds to the initializer expression lvalue in the first case and to the lvalue result of the conversion in the second case (or, in either case, to the appropriate base class subobject of the object). \begin{note} The usual lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, and function-to-pointer\iref{conv.func} standard conversions are not needed, and therefore are suppressed, when such direct bindings to lvalues are done. \end{note} \begin{example} \begin{codeblock} double d = 2.0; double& rd = d; // \tcode{rd} refers to \tcode{d} const double& rcd = d; // \tcode{rcd} refers to \tcode{d} struct A { }; struct B : A { operator int&(); } b; A& ra = b; // \tcode{ra} refers to \tcode{A} subobject in \tcode{b} const A& rca = b; // \tcode{rca} refers to \tcode{A} subobject in \tcode{b} int& ir = B(); // \tcode{ir} refers to the result of \tcode{B::operator int\&} \end{codeblock} \end{example} \item Otherwise, if the reference is an lvalue reference to a type that is not const-qualified or is volatile-qualified, the program is ill-formed. \begin{example} \begin{codeblock} double& rd2 = 2.0; // error: not an lvalue and reference not \keyword{const} int i = 2; double& rd3 = i; // error: type mismatch and reference not \keyword{const} \end{codeblock} \end{example} \item Otherwise, if the initializer expression \begin{itemize} \item is an rvalue (but not a bit-field) or function lvalue and ``\cvqual{cv1} \tcode{T1}'' is reference-compatible with ``\cvqual{cv2} \tcode{T2}'', or \item has a class type (i.e., \tcode{T2} is a class type), where \tcode{T1} is not reference-related to \tcode{T2}, and can be converted to an rvalue or function lvalue of type ``\cvqual{cv3} \tcode{T3}'', where ``\cvqual{cv1} \tcode{T1}'' is reference-compatible with ``\cvqual{cv3} \tcode{T3}'' (see~\ref{over.match.ref}), \end{itemize} then the initializer expression in the first case and the converted expression in the second case is called the converted initializer. If the converted initializer is a prvalue, its type \tcode{T4} is adjusted to type ``\cvqual{cv1} \tcode{T4}''\iref{conv.qual} and the temporary materialization conversion\iref{conv.rval} is applied. In any case, the reference binds to the resulting glvalue (or to an appropriate base class subobject). \begin{example} \begin{codeblock} struct A { }; struct B : A { } b; extern B f(); const A& rca2 = f(); // binds to the \tcode{A} subobject of the \tcode{B} rvalue. A&& rra = f(); // same as above struct X { operator B(); operator int&(); } x; const A& r = x; // binds to the \tcode{A} subobject of the result of the conversion int i2 = 42; int&& rri = static_cast(i2); // binds directly to \tcode{i2} B&& rrb = x; // binds directly to the result of \tcode{operator B} \end{codeblock} \end{example} \item Otherwise: \begin{itemize} \item If \tcode{T1} or \tcode{T2} is a class type and \tcode{T1} is not reference-related to \tcode{T2}, user-defined conversions are considered using the rules for copy-initialization of an object of type ``\cvqual{cv1} \tcode{T1}'' by user-defined conversion\iref{dcl.init,over.match.copy,over.match.conv}; the program is ill-formed if the corresponding non-reference copy-initialization would be ill-formed. The result of the call to the conversion function, as described for the non-reference copy-initialization, is then used to direct-initialize the reference. For this direct-initialization, user-defined conversions are not considered. \item Otherwise, the initializer expression is implicitly converted to a prvalue of type ``\tcode{T1}''. The temporary materialization conversion is applied, considering the type of the prvalue to be ``\cvqual{cv1} \tcode{T1}'', and the reference is bound to the result. \end{itemize} If \tcode{T1} is reference-related to \tcode{T2}: \begin{itemize} \item \cvqual{cv1} shall be the same cv-qualification as, or greater cv-qualification than, \cvqual{cv2}; and \item if the reference is an rvalue reference, the initializer expression shall not be an lvalue. \begin{note} This can be affected by whether the initializer expression is move-eligible\iref{expr.prim.id.unqual}. \end{note} \end{itemize} \begin{example} \begin{codeblock} struct Banana { }; struct Enigma { operator const Banana(); }; struct Alaska { operator Banana&(); }; void enigmatic() { typedef const Banana ConstBanana; Banana &&banana1 = ConstBanana(); // error Banana &&banana2 = Enigma(); // error Banana &&banana3 = Alaska(); // error } const double& rcd2 = 2; // \tcode{rcd2} refers to temporary with value \tcode{2.0} double&& rrd = 2; // \tcode{rrd} refers to temporary with value \tcode{2.0} const volatile int cvi = 1; const int& r2 = cvi; // error: cv-qualifier dropped struct A { operator volatile int&(); } a; const int& r3 = a; // error: cv-qualifier dropped // from result of conversion function double d2 = 1.0; double&& rrd2 = d2; // error: initializer is lvalue of related type struct X { operator int&(); }; int&& rri2 = X(); // error: result of conversion function is lvalue of related type int i3 = 2; double&& rrd3 = i3; // \tcode{rrd3} refers to temporary with value \tcode{2.0} \end{codeblock} \end{example} \end{itemize} In all cases except the last (i.e., implicitly converting the initializer expression to the referenced type), the reference is said to \defn{bind directly} to the initializer expression. \pnum \begin{note} \ref{class.temporary} describes the lifetime of temporaries bound to references. \end{note} \rSec2[dcl.init.list]{List-initialization}% \indextext{initialization!list-initialization|(} \pnum \defnx{List-initialization}{list-initialization} is initialization of an object or reference from a \grammarterm{braced-init-list}. Such an initializer is called an \term{initializer list}, and the comma-separated \grammarterm{initializer-clause}{s} of the \grammarterm{initializer-list} or \grammarterm{designated-initializer-clause}{s} of the \grammarterm{designated-initializer-list} are called the \term{elements} of the initializer list. An initializer list may be empty. List-initialization can occur in direct-initialization or copy-initialization contexts; list-initialization in a direct-initialization context is called \defn{direct-list-initialization} and list-initialization in a copy-initialization context is called \defn{copy-list-initialization}. \begin{note} List-initialization can be used \begin{itemize} \item as the initializer in a variable definition\iref{dcl.init} \item as the initializer in a \grammarterm{new-expression}\iref{expr.new} \item in a \tcode{return} statement\iref{stmt.return} \item as a \grammarterm{for-range-initializer}\iref{stmt.iter} \item as a function argument\iref{expr.call} \item as a subscript\iref{expr.sub} \item as an argument to a constructor invocation\iref{dcl.init,expr.type.conv} \item as an initializer for a non-static data member\iref{class.mem} \item in a \grammarterm{mem-initializer}\iref{class.base.init} \item on the right-hand side of an assignment\iref{expr.ass} \end{itemize} \begin{example} \begin{codeblock} int a = {1}; std::complex z{1,2}; new std::vector{"once", "upon", "a", "time"}; // 4 string elements f( {"Nicholas","Annemarie"} ); // pass list of two elements return { "Norah" }; // return list of one element int* e {}; // initialization to zero / null pointer x = double{1}; // explicitly construct a \tcode{double} std::map anim = { {"bear",4}, {"cassowary",2}, {"tiger",7} }; \end{codeblock} \end{example} \end{note} \pnum A constructor is an \defn{initializer-list constructor} if its first parameter is of type \tcode{std::initializer_list} or reference to \cv{}~\tcode{std::initializer_list} for some type \tcode{E}, and either there are no other parameters or else all other parameters have default arguments\iref{dcl.fct.default}. \begin{note} Initializer-list constructors are favored over other constructors in list-initialization\iref{over.match.list}. Passing an initializer list as the argument to the constructor template \tcode{template C(T)} of a class \tcode{C} does not create an initializer-list constructor, because an initializer list argument causes the corresponding parameter to be a non-deduced context\iref{temp.deduct.call}. \end{note} The template \tcode{std::initializer_list} is not predefined; if a standard library declaration\iref{initializer.list.syn,std.modules} of \tcode{std::initializer_list} is not reachable from\iref{module.reach} a use of \tcode{std::initializer_list} --- even an implicit use in which the type is not named\iref{dcl.spec.auto} --- the program is ill-formed. \pnum List-initialization of an object or reference of type \tcode{T} is defined as follows: \begin{itemize} \item If the \grammarterm{braced-init-list} contains a \grammarterm{designated-initializer-list}, \tcode{T} shall be an aggregate class. The ordered \grammarterm{identifier}{s} in the \grammarterm{designator}{s} of the \grammarterm{designated-initializer-list} shall form a subsequence of the ordered \grammarterm{identifier}{s} in the direct non-static data members of \tcode{T}. Aggregate initialization is performed\iref{dcl.init.aggr}. \begin{example} \begin{codeblock} struct A { int x; int y; int z; }; A a{.y = 2, .x = 1}; // error: designator order does not match declaration order A b{.x = 1, .z = 2}; // OK, \tcode{b.y} initialized to \tcode{0} \end{codeblock} \end{example} \item If \tcode{T} is an aggregate class and the initializer list has a single element of type \cvqual{cv} \tcode{U}, where \tcode{U} is \tcode{T} or a class derived from \tcode{T}, the object is initialized from that element (by copy-initialization for copy-list-initialization, or by direct-initialization for direct-list-initialization). \item Otherwise, if \tcode{T} is a character array and the initializer list has a single element that is an appropriately-typed \grammarterm{string-literal}\iref{dcl.init.string}, initialization is performed as described in that subclause. \item Otherwise, if \tcode{T} is an aggregate, aggregate initialization is performed\iref{dcl.init.aggr}. \begin{example} \begin{codeblock} double ad[] = { 1, 2.0 }; // OK int ai[] = { 1, 2.0 }; // error: narrowing struct S2 { int m1; double m2, m3; }; S2 s21 = { 1, 2, 3.0 }; // OK S2 s22 { 1.0, 2, 3 }; // error: narrowing S2 s23 { }; // OK, default to 0,0,0 \end{codeblock} \end{example} \item Otherwise, if the initializer list has no elements and \tcode{T} is a class type with a default constructor, the object is value-initialized. \item Otherwise, if \tcode{T} is a specialization of \tcode{std::initializer_list}, the object is constructed as described below. \item Otherwise, if \tcode{T} is a class type, constructors are considered. The applicable constructors are enumerated and the best one is chosen through overload resolution\iref{over.match,over.match.list}. If a narrowing conversion (see below) is required to convert any of the arguments, the program is ill-formed. \begin{example} \begin{codeblock} struct S { S(std::initializer_list); // \#1 S(std::initializer_list); // \#2 S(); // \#3 // ... }; S s1 = { 1.0, 2.0, 3.0 }; // invoke \#1 S s2 = { 1, 2, 3 }; // invoke \#2 S s3 = { }; // invoke \#3 \end{codeblock} \end{example} \begin{example} \begin{codeblock} struct Map { Map(std::initializer_list>); }; Map ship = {{"Sophie",14}, {"Surprise",28}}; \end{codeblock} \end{example} \begin{example} \begin{codeblock} struct S { // no initializer-list constructors S(int, double, double); // \#1 S(); // \#2 // ... }; S s1 = { 1, 2, 3.0 }; // OK, invoke \#1 S s2 { 1.0, 2, 3 }; // error: narrowing S s3 { }; // OK, invoke \#2 \end{codeblock} \end{example} \item Otherwise, if \tcode{T} is an enumeration with a fixed underlying type\iref{dcl.enum} \tcode{U}, the \grammarterm{initializer-list} has a single element \tcode{v}, \tcode{v} can be implicitly converted to \tcode{U}, and the initialization is direct-list-initialization, the object is initialized with the value \tcode{T(v)}\iref{expr.type.conv}; if a narrowing conversion is required to convert \tcode{v} to \tcode{U}, the program is ill-formed. \begin{example} \begin{codeblock} enum byte : unsigned char { }; byte b { 42 }; // OK byte c = { 42 }; // error byte d = byte{ 42 }; // OK; same value as \tcode{b} byte e { -1 }; // error struct A { byte b; }; A a1 = { { 42 } }; // error A a2 = { byte{ 42 } }; // OK void f(byte); f({ 42 }); // error enum class Handle : uint32_t { Invalid = 0 }; Handle h { 42 }; // OK \end{codeblock} \end{example} \item Otherwise, if the initializer list has a single element of type \tcode{E} and either \tcode{T} is not a reference type or its referenced type is reference-related to \tcode{E}, the object or reference is initialized from that element (by copy-initialization for copy-list-initialization, or by direct-initialization for direct-list-initialization); if a narrowing conversion (see below) is required to convert the element to \tcode{T}, the program is ill-formed. \begin{example} \begin{codeblock} int x1 {2}; // OK int x2 {2.0}; // error: narrowing \end{codeblock} \end{example} \item Otherwise, if \tcode{T} is a reference type, a prvalue is generated. The prvalue initializes its result object by copy-list-initialization from the initializer list. The prvalue is then used to direct-initialize the reference. The type of the prvalue is the type referenced by \tcode{T}, unless \tcode{T} is ``reference to array of unknown bound of \tcode{U}'', in which case the type of the prvalue is the type of \tcode{x} in the declaration \tcode{U x[] $H$}, where $H$ is the initializer list. \begin{note} As usual, the binding will fail and the program is ill-formed if the reference type is an lvalue reference to a non-const type. \end{note} \begin{example} \begin{codeblock} struct S { S(std::initializer_list); // \#1 S(const std::string&); // \#2 // ... }; const S& r1 = { 1, 2, 3.0 }; // OK, invoke \#1 const S& r2 { "Spinach" }; // OK, invoke \#2 S& r3 = { 1, 2, 3 }; // error: initializer is not an lvalue const int& i1 = { 1 }; // OK const int& i2 = { 1.1 }; // error: narrowing const int (&iar)[2] = { 1, 2 }; // OK, \tcode{iar} is bound to temporary array struct A { } a; struct B { explicit B(const A&); }; const B& b2{a}; // error: cannot copy-list-initialize \tcode{B} temporary from \tcode{A} \end{codeblock} \end{example} \item Otherwise, if the initializer list has no elements, the object is value-initialized. \begin{example} \begin{codeblock} int** pp {}; // initialized to null pointer \end{codeblock} \end{example} \item Otherwise, the program is ill-formed. \begin{example} \begin{codeblock} struct A { int i; int j; }; A a1 { 1, 2 }; // aggregate initialization A a2 { 1.2 }; // error: narrowing struct B { B(std::initializer_list); }; B b1 { 1, 2 }; // creates \tcode{initializer_list} and calls constructor B b2 { 1, 2.0 }; // error: narrowing struct C { C(int i, double j); }; C c1 = { 1, 2.2 }; // calls constructor with arguments (1, 2.2) C c2 = { 1.1, 2 }; // error: narrowing int j { 1 }; // initialize to 1 int k { }; // initialize to 0 \end{codeblock} \end{example} \end{itemize} \pnum Within the \grammarterm{initializer-list} of a \grammarterm{braced-init-list}, the \grammarterm{initializer-clause}{s}, including any that result from pack expansions\iref{temp.variadic}, are evaluated in the order in which they appear. That is, every value computation and side effect associated with a given \grammarterm{initializer-clause} is sequenced before every value computation and side effect associated with any \grammarterm{initializer-clause} that follows it in the comma-separated list of the \grammarterm{initializer-list}. \begin{note} This evaluation ordering holds regardless of the semantics of the initialization; for example, it applies when the elements of the \grammarterm{initializer-list} are interpreted as arguments of a constructor call, even though ordinarily there are no sequencing constraints on the arguments of a call. \end{note} \pnum An object of type \tcode{std::initializer_list} is constructed from an initializer list as if the implementation generated and materialized\iref{conv.rval} a prvalue of type ``array of $N$ \tcode{const E}'', where $N$ is the number of elements in the initializer list. Each element of that array is copy-initialized with the corresponding element of the initializer list, and the \tcode{std::initializer_list} object is constructed to refer to that array. \begin{note} A constructor or conversion function selected for the copy is required to be accessible\iref{class.access} in the context of the initializer list. \end{note} If a narrowing conversion is required to initialize any of the elements, the program is ill-formed. \begin{example} \begin{codeblock} struct X { X(std::initializer_list v); }; X x{ 1,2,3 }; \end{codeblock} The initialization will be implemented in a way roughly equivalent to this: \begin{codeblock} const double __a[3] = {double{1}, double{2}, double{3}}; X x(std::initializer_list(__a, __a+3)); \end{codeblock} assuming that the implementation can construct an \tcode{initializer_list} object with a pair of pointers. \end{example} \pnum The array has the same lifetime as any other temporary object\iref{class.temporary}, except that initializing an \tcode{initiali\-zer_list} object from the array extends the lifetime of the array exactly like binding a reference to a temporary. \begin{example} \begin{codeblock} typedef std::complex cmplx; std::vector v1 = { 1, 2, 3 }; void f() { std::vector v2{ 1, 2, 3 }; std::initializer_list i3 = { 1, 2, 3 }; } struct A { std::initializer_list i4; A() : i4{ 1, 2, 3 } {} // ill-formed, would create a dangling reference }; \end{codeblock} For \tcode{v1} and \tcode{v2}, the \tcode{initializer_list} object is a parameter in a function call, so the array created for \tcode{\{ 1, 2, 3 \}} has full-expression lifetime. For \tcode{i3}, the \tcode{initializer_list} object is a variable, so the array persists for the lifetime of the variable. For \tcode{i4}, the \tcode{initializer_list} object is initialized in the constructor's \grammarterm{ctor-initializer} as if by binding a temporary array to a reference member, so the program is ill-formed\iref{class.base.init}. \end{example} \begin{note} The implementation is free to allocate the array in read-only memory if an explicit array with the same initializer can be so allocated. \end{note} \pnum A \defnadj{narrowing}{conversion} is an implicit conversion \begin{itemize} \item from a floating-point type to an integer type, or \item from a floating-point type \tcode{T} to another floating-point type whose floating-point conversion rank is neither greater than nor equal to that of \tcode{T}, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly), or \item from an integer type or unscoped enumeration type to a floating-point type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type, or \item from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where \begin{itemize} \item the source is a bit-field whose width $w$ is less than that of its type (or, for an enumeration type, its underlying type) and the target type can represent all the values of a hypothetical extended integer type with width $w$ and with the same signedness as the original type or \item the source is a constant expression whose value after integral promotions will fit into the target type, or \end{itemize} \item from a pointer type or a pointer-to-member type to \tcode{bool}. \end{itemize} \begin{note} As indicated above, such conversions are not allowed at the top level in list-initializations. \end{note} \begin{example} \begin{codeblock} int x = 999; // \tcode{x} is not a constant expression const int y = 999; const int z = 99; char c1 = x; // OK, though it potentially narrows (in this case, it does narrow) char c2{x}; // error: potentially narrows char c3{y}; // error: narrows (assuming \tcode{char} is 8 bits) char c4{z}; // OK, no narrowing needed unsigned char uc1 = {5}; // OK, no narrowing needed unsigned char uc2 = {-1}; // error: narrows unsigned int ui1 = {-1}; // error: narrows signed int si1 = { (unsigned int)-1 }; // error: narrows int ii = {2.0}; // error: narrows float f1 { x }; // error: potentially narrows float f2 { 7 }; // OK, 7 can be exactly represented as a \tcode{float} bool b = {"meow"}; // error: narrows int f(int); int a[] = { 2, f(2), f(2.0) }; // OK, the \tcode{double}-to-\tcode{int} conversion is not at the top level \end{codeblock} \end{example} \indextext{initialization!list-initialization|)}% \indextext{initialization|)}% \indextext{declarator|)} \rSec1[dcl.fct.def]{Function definitions}% \indextext{definition!function|(} \rSec2[dcl.fct.def.general]{In general} \pnum \indextext{body!function}% Function definitions have the form \indextext{\idxgram{function-definition}}% % \begin{bnf} \nontermdef{function-definition}\br \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator \opt{virt-specifier-seq} function-body\br \opt{attribute-specifier-seq} \opt{decl-specifier-seq} declarator requires-clause function-body \end{bnf} \begin{bnf} \nontermdef{function-body}\br \opt{ctor-initializer} compound-statement\br function-try-block\br \terminal{=} \keyword{default} \terminal{;}\br \terminal{=} \keyword{delete} \terminal{;} \end{bnf} Any informal reference to the body of a function should be interpreted as a reference to the non-terminal \grammarterm{function-body}. The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{function-definition} appertains to the function. A \grammarterm{virt-specifier-seq} can be part of a \grammarterm{function-definition} only if it is a \grammarterm{member-declaration}\iref{class.mem}. \pnum In a \grammarterm{function-definition}, either \keyword{void} \grammarterm{declarator} \tcode{;} or \grammarterm{declarator} \tcode{;} shall be a well-formed function declaration as described in~\ref{dcl.fct}. A function shall be defined only in namespace or class scope. The type of a parameter or the return type for a function definition shall not be a (possibly cv-qualified) class type that is incomplete or abstract within the function body unless the function is deleted\iref{dcl.fct.def.delete}. \pnum \begin{example} A simple example of a complete function definition is \begin{codeblock} int max(int a, int b, int c) { int m = (a > b) ? a : b; return (m > c) ? m : c; } \end{codeblock} Here \tcode{int} is the \grammarterm{decl-specifier-seq}; \tcode{max(int} \tcode{a,} \tcode{int} \tcode{b,} \tcode{int} \tcode{c)} is the \grammarterm{declarator}; \tcode{\{ \commentellip{} \}} is the \grammarterm{function-body}. \end{example} \pnum \indextext{initializer!base class}% \indextext{initializer!member}% \indextext{definition!constructor}% A \grammarterm{ctor-initializer} is used only in a constructor; see~\ref{class.ctor} and~\ref{class.init}. \pnum \begin{note} A \grammarterm{cv-qualifier-seq} affects the type of \keyword{this} in the body of a member function; see~\ref{expr.prim.this}. \end{note} \pnum \begin{note} Unused parameters need not be named. For example, \begin{codeblock} void print(int a, int) { std::printf("a = %d\n",a); } \end{codeblock} \end{note} \pnum A \defnadj{function-local predefined}{variable} is a variable with static storage duration that is implicitly defined in a function parameter scope. \pnum \indextext{__func__@\mname{func}}% The function-local predefined variable \mname{func} is defined as if a definition of the form \begin{codeblock} static const char __func__[] = "@\placeholder{function-name}@"; \end{codeblock} had been provided, where \tcode{\placeholder{function-name}} is an \impldef{string resulting from \mname{func}} string. It is unspecified whether such a variable has an address distinct from that of any other object in the program. \begin{footnote} Implementations are permitted to provide additional predefined variables with names that are reserved to the implementation\iref{lex.name}. If a predefined variable is not odr-used\iref{term.odr.use}, its string value need not be present in the program image. \end{footnote} \begin{example} \begin{codeblock} struct S { S() : s(__func__) { } // OK const char* s; }; void f(const char* s = __func__); // error: \mname{func} is undeclared \end{codeblock} \end{example} \rSec2[dcl.fct.def.default]{Explicitly-defaulted functions}% \pnum A function definition whose \grammarterm{function-body} is of the form \tcode{= default ;} is called an \defnx{explicitly-defaulted}{definition!function!explicitly-defaulted} definition. A function that is explicitly defaulted shall \begin{itemize} \item be a special member function or a comparison operator function\iref{over.binary}, and \item not have default arguments. \end{itemize} \pnum An explicitly defaulted special member function $\tcode{F}_1$ is allowed to differ from the corresponding special member function $\tcode{F}_2$ that would have been implicitly declared, as follows: \begin{itemize} \item $\tcode{F}_1$ and $\tcode{F}_2$ may have differing \grammarterm{ref-qualifier}{s}; \item if $\tcode{F}_2$ has an implicit object parameter of type ``reference to \tcode{C}'', $\tcode{F}_1$ may be an explicit object member function whose explicit object parameter is of type ``reference to \tcode{C}'', in which case the type of $\tcode{F}_1$ would differ from the type of $\tcode{F}_2$ in that the type of $\tcode{F}_1$ has an additional parameter; \item $\tcode{F}_1$ and $\tcode{F}_2$ may have differing exception specifications; and \item if $\tcode{F}_2$ has a non-object parameter of type \tcode{const C\&}, the corresponding non-object parameter of $\tcode{F}_1$ may be of type \tcode{C\&}. \end{itemize} If the type of $\tcode{F}_1$ differs from the type of $\tcode{F}_2$ in a way other than as allowed by the preceding rules, then: \begin{itemize} \item if $\tcode{F}_1$ is an assignment operator, and the return type of $\tcode{F}_1$ differs from the return type of $\tcode{F}_2$ or $\tcode{F}_1${'s} non-object parameter type is not a reference, the program is ill-formed; \item otherwise, if $\tcode{F}_1$ is explicitly defaulted on its first declaration, it is defined as deleted; \item otherwise, the program is ill-formed. \end{itemize} \pnum A function explicitly defaulted on its first declaration is implicitly inline\iref{dcl.inline}, and is implicitly constexpr\iref{dcl.constexpr} if it is constexpr-suitable. \pnum \begin{example} \begin{codeblock} struct S { S(int a = 0) = default; // error: default argument void operator=(const S&) = default; // error: non-matching return type ~S() noexcept(false) = default; // OK, despite mismatched exception specification private: int i; S(S&); // OK, private copy constructor }; S::S(S&) = default; // OK, defines copy constructor struct T { T(); T(T &&) noexcept(false); }; struct U { T t; U(); U(U &&) noexcept = default; }; U u1; U u2 = static_cast(u1); // OK, calls \tcode{std::terminate} if \tcode{T::T(T\&\&)} throws \end{codeblock} \end{example} \pnum Explicitly-defaulted functions and implicitly-declared functions are collectively called \defn{defaulted} functions, and the implementation shall provide implicit definitions for them\iref{class.ctor,class.dtor,class.copy.ctor,class.copy.assign} as described below, including possibly defining them as deleted. A defaulted prospective destructor\iref{class.dtor} that is not a destructor is defined as deleted. A defaulted special member function that is neither a prospective destructor nor an eligible special member function\iref{special} is defined as deleted. A function is \defn{user-provided} if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is implicitly defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed. A non-user-provided defaulted function (i.e., implicitly declared or explicitly defaulted in the class) that is not defined as deleted is implicitly defined when it is odr-used\iref{basic.def.odr} or needed for constant evaluation\iref{expr.const}. \begin{note} Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base. \end{note} \pnum \begin{example} \begin{codeblock} struct trivial { trivial() = default; trivial(const trivial&) = default; trivial(trivial&&) = default; trivial& operator=(const trivial&) = default; trivial& operator=(trivial&&) = default; ~trivial() = default; }; struct nontrivial1 { nontrivial1(); }; nontrivial1::nontrivial1() = default; // not first declaration \end{codeblock} \end{example} \rSec2[dcl.fct.def.delete]{Deleted definitions}% \indextext{definition!function!deleted}% \pnum A \defnadj{deleted}{definition} of a function is a function definition whose \grammarterm{function-body} is of the form \tcode{= delete ;} or an explicitly-defaulted definition of the function where the function is defined as deleted. A \defnadj{deleted}{function} is a function with a deleted definition or a function that is implicitly defined as deleted. \pnum A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed. \begin{note} This includes calling the function implicitly or explicitly and forming a pointer or pointer-to-member to the function. It applies even for references in expressions that are not potentially-evaluated. For an overload set, only the function selected by overload resolution is referenced. The implicit odr-use\iref{term.odr.use} of a virtual function does not, by itself, constitute a reference. \end{note} \pnum \begin{example} One can prevent default initialization and initialization by non-\tcode{double}s with \begin{codeblock} struct onlydouble { onlydouble() = delete; // OK, but redundant template onlydouble(T) = delete; onlydouble(double); }; \end{codeblock} \end{example} \begin{example} One can prevent use of a class in certain \grammarterm{new-expression}{s} by using deleted definitions of a user-declared \tcode{operator new} for that class. \begin{codeblock} struct sometype { void* operator new(std::size_t) = delete; void* operator new[](std::size_t) = delete; }; sometype* p = new sometype; // error: deleted class \tcode{operator new} sometype* q = new sometype[3]; // error: deleted class \tcode{operator new[]} \end{codeblock} \end{example} \begin{example} One can make a class uncopyable, i.e., move-only, by using deleted definitions of the copy constructor and copy assignment operator, and then providing defaulted definitions of the move constructor and move assignment operator. \begin{codeblock} struct moveonly { moveonly() = default; moveonly(const moveonly&) = delete; moveonly(moveonly&&) = default; moveonly& operator=(const moveonly&) = delete; moveonly& operator=(moveonly&&) = default; ~moveonly() = default; }; moveonly* p; moveonly q(*p); // error: deleted copy constructor \end{codeblock} \end{example} \pnum A deleted function is implicitly an inline function\iref{dcl.inline}. \begin{note} The one-definition rule\iref{basic.def.odr} applies to deleted definitions. \end{note} A deleted definition of a function shall be the first declaration of the function or, for an explicit specialization of a function template, the first declaration of that specialization. An implicitly declared allocation or deallocation function\iref{basic.stc.dynamic} shall not be defined as deleted. \begin{example} \begin{codeblock} struct sometype { sometype(); }; sometype::sometype() = delete; // error: not first declaration \end{codeblock} \end{example} \indextext{definition!function|)} \rSec2[dcl.fct.def.coroutine]{Coroutine definitions}% \indextext{definition!coroutine}% \pnum A function is a \defn{coroutine} if its \grammarterm{function-body} encloses a \grammarterm{coroutine-return-statement}\iref{stmt.return.coroutine}, an \grammarterm{await-expression}\iref{expr.await}, or a \grammarterm{yield-expression}\iref{expr.yield}. The \grammarterm{parameter-declaration-clause} of the coroutine shall not terminate with an ellipsis that is not part of a \grammarterm{parameter-declaration}. \pnum \begin{example} \begin{codeblock} task f(); task g1() { int i = co_await f(); std::cout << "f() => " << i << std::endl; } template task g2(Args&&...) { // OK, ellipsis is a pack expansion int i = co_await f(); std::cout << "f() => " << i << std::endl; } task g3(int a, ...) { // error: variable parameter list not allowed int i = co_await f(); std::cout << "f() => " << i << std::endl; } \end{codeblock} \end{example} \pnum \indextext{promise type|see{coroutine, promise type}}% The \defnx{promise type}{coroutine!promise type} of a coroutine is \tcode{std::coroutine_traits::promise_type}, where \tcode{R} is the return type of the function, and $\tcode{P}_1 \dotsc \tcode{P}_n$ is the sequence of types of the non-object function parameters, preceded by the type of the object parameter\iref{dcl.fct} if the coroutine is a non-static member function. The promise type shall be a class type. \pnum In the following, $\tcode{p}_i$ is an lvalue of type $\tcode{P}_i$, where $\tcode{p}_1$ denotes the object parameter and $\tcode{p}_{i+1}$ denotes the $i^\text{th}$ non-object function parameter for a non-static member function, and $\tcode{p}_i$ denotes the $i^\text{th}$ function parameter otherwise. For a non-static member function, $\tcode{q}_1$ is an lvalue that denotes \tcode{*this}; any other $\tcode{q}_i$ is an lvalue that denotes the parameter copy corresponding to $\tcode{p}_i$, as described below. \pnum A coroutine behaves as if its \grammarterm{function-body} were replaced by: \begin{ncsimplebnf} \terminal{\{}\br \bnfindent \placeholder{promise-type} \exposid{promise} \placeholder{promise-constructor-arguments} \terminal{;}\br % FIXME: \bnfindent \exposid{promise}\terminal{.get_return_object()} \terminal{;} % ... except that it's not a discarded-value expression \bnfindent \terminal{try} \terminal{\{}\br \bnfindent\bnfindent \terminal{co_await} \terminal{\exposid{promise}.initial_suspend()} \terminal{;}\br \bnfindent\bnfindent function-body\br \bnfindent \terminal{\} catch ( ... ) \{}\br \bnfindent\bnfindent \terminal{if (!\exposid{initial-await-resume-called})}\br \bnfindent\bnfindent\bnfindent \terminal{throw} \terminal{;}\br \bnfindent\bnfindent \terminal{\exposid{promise}.unhandled_exception()} \terminal{;}\br \bnfindent \terminal{\}}\br \exposid{final-suspend} \terminal{:}\br \bnfindent \terminal{co_await} \terminal{\exposid{promise}.final_suspend()} \terminal{;}\br \terminal{\}} \end{ncsimplebnf} where \begin{itemize} \item \indextext{coroutine!await expression}% the \grammarterm{await-expression} containing the call to \tcode{initial_suspend} is the \defnadj{initial}{await expression}, and \item the \grammarterm{await-expression} containing the call to \tcode{final_suspend} is the \defnadj{final}{await expression}, and \item \placeholder{initial-await-resume-called} is initially \tcode{false} and is set to \tcode{true} immediately before the evaluation of the \placeholder{await-resume} expression\iref{expr.await} of the initial await expression, and \item \placeholder{promise-type} denotes the promise type, and \item the object denoted by the exposition-only name \exposid{promise} is the \defn{promise object} of the coroutine, and \item the label denoted by the name \exposid{final-suspend} is defined for exposition only\iref{stmt.return.coroutine}, and \item \placeholder{promise-constructor-arguments} is determined as follows: overload resolution is performed on a promise constructor call created by assembling an argument list $\tcode{q}_1 \dotsc \tcode{q}_n$. If a viable constructor is found\iref{over.match.viable}, then \placeholder{promise-constructor-arguments} is \tcode{($\tcode{q}_1$, $\dotsc$, $\tcode{q}_n$)}, otherwise \placeholder{promise-constructor-arguments} is empty, and \item a coroutine is suspended at the \defnadj{initial}{suspend point} if it is suspended at the initial await expression, and \item a coroutine is suspended at a \defnadj{final}{suspend point} if it is suspended \begin{itemize} \item at a final await expression or \item due to an exception exiting from \tcode{unhandled_exception()}. \end{itemize} \end{itemize} \pnum If searches for the names \tcode{return_void} and \tcode{return_value} in the scope of the promise type each find any declarations, the program is ill-formed. \begin{note} If \tcode{return_void} is found, flowing off the end of a coroutine is equivalent to a \keyword{co_return} with no operand. Otherwise, flowing off the end of a coroutine results in undefined behavior\iref{stmt.return.coroutine}. \end{note} \pnum The expression \tcode{\exposid{promise}.get_return_object()} is used to initialize the returned reference or prvalue result object of a call to a coroutine. The call to \tcode{get_return_object} is sequenced before the call to \tcode{initial_suspend} and is invoked at most once. \pnum A suspended coroutine can be resumed to continue execution by invoking a resumption member function\iref{coroutine.handle.resumption} of a coroutine handle\iref{coroutine.handle} that refers to the coroutine. The evaluation that invoked a resumption member function is called the \defnx{resumer}{coroutine!resumer}. Invoking a resumption member function for a coroutine that is not suspended results in undefined behavior. \pnum An implementation may need to allocate additional storage for a coroutine. This storage is known as the \defn{coroutine state} and is obtained by calling a non-array allocation function\iref{basic.stc.dynamic.allocation}. The allocation function's name is looked up by searching for it in the scope of the promise type. \begin{itemize} \item If the search finds any declarations, overload resolution is performed on a function call created by assembling an argument list. The first argument is the amount of space requested, and is a prvalue of type \tcode{std::size_t}. The lvalues $\tcode{p}_1 \dotsc \tcode{p}_n$ are the successive arguments. If no viable function is found\iref{over.match.viable}, overload resolution is performed again on a function call created by passing just the amount of space required as a prvalue of type \tcode{std::size_t}. \item If the search finds no declarations, a search is performed in the global scope. Overload resolution is performed on a function call created by passing the amount of space required as a prvalue of type \tcode{std::size_t}. \end{itemize} \pnum If a search for the name \tcode{get_return_object_on_allocation_failure} in the scope of the promise type\iref{class.member.lookup} finds any declarations, then the result of a call to an allocation function used to obtain storage for the coroutine state is assumed to return \keyword{nullptr} if it fails to obtain storage, and if a global allocation function is selected, the \tcode{::operator new(size_t, nothrow_t)} form is used. The allocation function used in this case shall have a non-throwing \grammarterm{noexcept-specifier}. If the allocation function returns \keyword{nullptr}, the coroutine returns control to the caller of the coroutine and the return value is obtained by a call to \tcode{T::get_return_object_on_allocation_failure()}, where \tcode{T} is the promise type. \begin{example} \begin{codeblock} #include #include // \tcode{::operator new(size_t, nothrow_t)} will be used if allocation is needed struct generator { struct promise_type; using handle = std::coroutine_handle; struct promise_type { int current_value; static auto get_return_object_on_allocation_failure() { return generator{nullptr}; } auto get_return_object() { return generator{handle::from_promise(*this)}; } auto initial_suspend() { return std::suspend_always{}; } auto final_suspend() noexcept { return std::suspend_always{}; } void unhandled_exception() { std::terminate(); } void return_void() {} auto yield_value(int value) { current_value = value; return std::suspend_always{}; } }; bool move_next() { return coro ? (coro.resume(), !coro.done()) : false; } int current_value() { return coro.promise().current_value; } generator(generator const&) = delete; generator(generator && rhs) : coro(rhs.coro) { rhs.coro = nullptr; } ~generator() { if (coro) coro.destroy(); } private: generator(handle h) : coro(h) {} handle coro; }; generator f() { co_yield 1; co_yield 2; } int main() { auto g = f(); while (g.move_next()) std::cout << g.current_value() << std::endl; } \end{codeblock} \end{example} \pnum The coroutine state is destroyed when control flows off the end of the coroutine or the \tcode{destroy} member function\iref{coroutine.handle.resumption} of a coroutine handle\iref{coroutine.handle} that refers to the coroutine is invoked. In the latter case, control in the coroutine is considered to be transferred out of the function\iref{stmt.dcl}. The storage for the coroutine state is released by calling a non-array deallocation function\iref{basic.stc.dynamic.deallocation}. If \tcode{destroy} is called for a coroutine that is not suspended, the program has undefined behavior. \pnum The deallocation function's name is looked up by searching for it in the scope of the promise type. If nothing is found, a search is performed in the global scope. If both a usual deallocation function with only a pointer parameter and a usual deallocation function with both a pointer parameter and a size parameter are found, then the selected deallocation function shall be the one with two parameters. Otherwise, the selected deallocation function shall be the function with one parameter. If no usual deallocation function is found, the program is ill-formed. The selected deallocation function shall be called with the address of the block of storage to be reclaimed as its first argument. If a deallocation function with a parameter of type \tcode{std::size_t} is used, the size of the block is passed as the corresponding argument. \pnum When a coroutine is invoked, after initializing its parameters\iref{expr.call}, a copy is created for each coroutine parameter. For a parameter of type \cv{}~\tcode{T}, the copy is a variable of type \cv{}~\tcode{T} with automatic storage duration that is direct-initialized from an xvalue of type \tcode{T} referring to the parameter. \begin{note} An original parameter object is never a const or volatile object\iref{basic.type.qualifier}. \end{note} The initialization and destruction of each parameter copy occurs in the context of the called coroutine. Initializations of parameter copies are sequenced before the call to the coroutine promise constructor and indeterminately sequenced with respect to each other. The lifetime of parameter copies ends immediately after the lifetime of the coroutine promise object ends. \begin{note} If a coroutine has a parameter passed by reference, resuming the coroutine after the lifetime of the entity referred to by that parameter has ended is likely to result in undefined behavior. \end{note} \pnum If the evaluation of the expression \tcode{\exposid{promise}.unhandled_exception()} exits via an exception, the coroutine is considered suspended at the final suspend point and the exception propagates to the caller or resumer. \pnum The expression \keyword{co_await} \tcode{\exposid{promise}.final_suspend()} shall not be potentially-throwing\iref{except.spec}. \rSec1[dcl.struct.bind]{Structured binding declarations}% \indextext{structured binding declaration}% \indextext{declaration!structured binding|see{structured binding declaration}}% \pnum A structured binding declaration introduces the \grammarterm{identifier}{s} $\tcode{v}_0$, $\tcode{v}_1$, $\tcode{v}_2, \dotsc$ of the \grammarterm{identifier-list} as names of \defn{structured binding}{s}. Let \cv{} denote the \grammarterm{cv-qualifier}{s} in the \grammarterm{decl-specifier-seq} and \placeholder{S} consist of the \grammarterm{storage-class-specifier}{s} of the \grammarterm{decl-specifier-seq} (if any). A \cv{} that includes \tcode{volatile} is deprecated; see~\ref{depr.volatile.type}. First, a variable with a unique name \exposid{e} is introduced. If the \grammarterm{assignment-expression} in the \grammarterm{initializer} has array type \cvqual{cv1} \tcode{A} and no \grammarterm{ref-qualifier} is present, \exposid{e} is defined by \begin{ncbnf} \opt{attribute-specifier-seq} \placeholder{S} \cv{} \terminal{A} \exposid{e} \terminal{;} \end{ncbnf} and each element is copy-initialized or direct-initialized from the corresponding element of the \grammarterm{assignment-expression} as specified by the form of the \grammarterm{initializer}. Otherwise, \exposid{e} is defined as-if by \begin{ncbnf} \opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \exposid{e} initializer \terminal{;} \end{ncbnf} where the declaration is never interpreted as a function declaration and the parts of the declaration other than the \grammarterm{declarator-id} are taken from the corresponding structured binding declaration. The type of the \grammarterm{id-expression} \exposid{e} is called \tcode{E}. \begin{note} \tcode{E} is never a reference type\iref{expr.prop}. \end{note} \pnum If the \grammarterm{initializer} refers to one of the names introduced by the structured binding declaration, the program is ill-formed. \pnum If \tcode{E} is an array type with element type \tcode{T}, the number of elements in the \grammarterm{identifier-list} shall be equal to the number of elements of \tcode{E}. Each $\tcode{v}_i$ is the name of an lvalue that refers to the element $i$ of the array and whose type is \tcode{T}; the referenced type is \tcode{T}. \begin{note} The top-level cv-qualifiers of \tcode{T} are \cv. \end{note} \begin{example} \begin{codeblock} auto f() -> int(&)[2]; auto [ x, y ] = f(); // \tcode{x} and \tcode{y} refer to elements in a copy of the array return value auto& [ xr, yr ] = f(); // \tcode{xr} and \tcode{yr} refer to elements in the array referred to by \tcode{f}'s return value \end{codeblock} \end{example} \pnum Otherwise, if the \grammarterm{qualified-id} \tcode{std::tuple_size} names a complete class type with a member named \tcode{value}, the expression \tcode{std::tuple_size::value} shall be a well-formed integral constant expression and the number of elements in the \grammarterm{identifier-list} shall be equal to the value of that expression. Let \tcode{i} be an index prvalue of type \tcode{std::size_t} corresponding to $\tcode{v}_i$. If a search for the name \tcode{get} in the scope of \tcode{E}\iref{class.member.lookup} finds at least one declaration that is a function template whose first template parameter is a non-type parameter, the initializer is \tcode{\exposidnc{e}.get()}. Otherwise, the initializer is \tcode{get(\exposid{e})}, where \tcode{get} undergoes argument-dependent lookup\iref{basic.lookup.argdep}. In either case, \tcode{get} is interpreted as a \grammarterm{template-id}. \begin{note} Ordinary unqualified lookup\iref{basic.lookup.unqual} is not performed. \end{note} In either case, \exposid{e} is an lvalue if the type of the entity \exposid{e} is an lvalue reference and an xvalue otherwise. Given the type $\tcode{T}_i$ designated by \tcode{std::tuple_element::type} and the type $\tcode{U}_i$ designated by either \tcode{$\tcode{T}_i$\&} or \tcode{$\tcode{T}_i$\&\&}, where $\tcode{U}_i$ is an lvalue reference if the initializer is an lvalue and an rvalue reference otherwise, variables are introduced with unique names $\tcode{r}_i$ as follows: \begin{ncbnf} \placeholder{S} \terminal{U$_i$ r$_i$ =} initializer \terminal{;} \end{ncbnf} Each $\tcode{v}_i$ is the name of an lvalue of type $\tcode{T}_i$ that refers to the object bound to $\tcode{r}_i$; the referenced type is $\tcode{T}_i$. \pnum Otherwise, all of \tcode{E}'s non-static data members shall be direct members of \tcode{E} or of the same base class of \tcode{E}, well-formed when named as \tcode{\exposidnc{e}.\placeholder{name}} in the context of the structured binding, \tcode{E} shall not have an anonymous union member, and the number of elements in the \grammarterm{identifier-list} shall be equal to the number of non-static data members of \tcode{E}. Designating the non-static data members of \tcode{E} as $\tcode{m}_0$, $\tcode{m}_1$, $\tcode{m}_2, \dotsc$ (in declaration order), each $\tcode{v}_i$ is the name of an lvalue that refers to the member \tcode{m}$_i$ of \exposid{e} and whose type is that of \tcode{\exposidnc{e}.$\tcode{m}_i$}\iref{expr.ref}; the referenced type is the declared type of $\tcode{m}_i$ if that type is a reference type, or the type of \tcode{\exposidnc{e}.$\tcode{m}_i$} otherwise. The lvalue is a bit-field if that member is a bit-field. \begin{example} \begin{codeblock} struct S { mutable int x1 : 2; volatile double y1; }; S f(); const auto [ x, y ] = f(); \end{codeblock} The type of the \grammarterm{id-expression} \tcode{x} is ``\tcode{int}'', the type of the \grammarterm{id-expression} \tcode{y} is ``\tcode{const volatile double}''. \end{example} \rSec1[enum]{Enumerations}% \rSec2[dcl.enum]{Enumeration declarations}% \indextext{enumeration}% \indextext{\idxcode{\{\}}!enum declaration@\tcode{enum} declaration}% \indextext{\idxcode{enum}!type of} \pnum An enumeration is a distinct type\iref{basic.compound} with named constants. Its name becomes an \grammarterm{enum-name} within its scope. \begin{bnf} \nontermdef{enum-name}\br identifier \end{bnf} \begin{bnf} \nontermdef{enum-specifier}\br enum-head \terminal{\{} \opt{enumerator-list} \terminal{\}}\br enum-head \terminal{\{} enumerator-list \terminal{,} \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{enum-head}\br enum-key \opt{attribute-specifier-seq} \opt{enum-head-name} \opt{enum-base} \end{bnf} \begin{bnf} \nontermdef{enum-head-name}\br \opt{nested-name-specifier} identifier \end{bnf} \begin{bnf} \nontermdef{opaque-enum-declaration}\br enum-key \opt{attribute-specifier-seq} enum-head-name \opt{enum-base} \terminal{;} \end{bnf} \begin{bnf} \nontermdef{enum-key}\br \keyword{enum}\br \keyword{enum} \keyword{class}\br \keyword{enum} \keyword{struct} \end{bnf} \begin{bnf} \nontermdef{enum-base}\br \terminal{:} type-specifier-seq \end{bnf} \begin{bnf} \nontermdef{enumerator-list}\br enumerator-definition\br enumerator-list \terminal{,} enumerator-definition \end{bnf} \begin{bnf} \nontermdef{enumerator-definition}\br enumerator\br enumerator \terminal{=} constant-expression \end{bnf} \begin{bnf} \nontermdef{enumerator}\br identifier \opt{attribute-specifier-seq} \end{bnf} The optional \grammarterm{attribute-specifier-seq} in the \grammarterm{enum-head} and the \grammarterm{opaque-enum-declaration} appertains to the enumeration; the attributes in that \grammarterm{attribute-specifier-seq} are thereafter considered attributes of the enumeration whenever it is named. A \tcode{:} following ``\keyword{enum} \opt{\grammarterm{nested-name-specifier}} \grammarterm{identifier}'' within the \grammarterm{decl-specifier-seq} of a \grammarterm{member-declaration} is parsed as part of an \grammarterm{enum-base}. \begin{note} This resolves a potential ambiguity between the declaration of an enumeration with an \grammarterm{enum-base} and the declaration of an unnamed bit-field of enumeration type. \begin{example} \begin{codeblock} struct S { enum E : int {}; enum E : int {}; // error: redeclaration of enumeration }; \end{codeblock} \end{example} \end{note} The \grammarterm{identifier} in an \grammarterm{enum-head-name} is not looked up and is introduced by the \grammarterm{enum-specifier} or \grammarterm{opaque-enum-declaration}. If the \grammarterm{enum-head-name} of an \grammarterm{opaque-enum-declaration} contains a \grammarterm{nested-name-specifier}, the declaration shall be an explicit specialization\iref{temp.expl.spec}. \pnum \indextext{constant!enumeration}% The enumeration type declared with an \grammarterm{enum-key} of only \keyword{enum} is an \defnadj{unscoped}{enumeration}, and its \grammarterm{enumerator}{s} are \defnx{unscoped enumerators}{enumerator!unscoped}. The \grammarterm{enum-key}{s} \tcode{enum class} and \tcode{enum struct} are semantically equivalent; an enumeration type declared with one of these is a \defnadj{scoped}{enumeration}, and its \grammarterm{enumerator}{s} are \defnx{scoped enumerators}{enumerator!scoped}. The optional \grammarterm{enum-head-name} shall not be omitted in the declaration of a scoped enumeration. The \grammarterm{type-specifier-seq} of an \grammarterm{enum-base} shall name an integral type; any cv-qualification is ignored. An \grammarterm{opaque-enum-declaration} declaring an unscoped enumeration shall not omit the \grammarterm{enum-base}. The identifiers in an \grammarterm{enumerator-list} are declared as constants, and can appear wherever constants are required. The same identifier shall not appear as the name of multiple enumerators in an \grammarterm{enumerator-list}. \indextext{enumerator!value of}% An \grammarterm{enumerator-definition} with \tcode{=} gives the associated \grammarterm{enumerator} the value indicated by the \grammarterm{constant-expression}. If the first \grammarterm{enumerator} has no \grammarterm{initializer}, the value of the corresponding constant is zero. An \grammarterm{enumerator-definition} without an \grammarterm{initializer} gives the \grammarterm{enumerator} the value obtained by increasing the value of the previous \grammarterm{enumerator} by one. \begin{example} \begin{codeblock} enum { a, b, c=0 }; enum { d, e, f=e+2 }; \end{codeblock} defines \tcode{a}, \tcode{c}, and \tcode{d} to be zero, \tcode{b} and \tcode{e} to be \tcode{1}, and \tcode{f} to be \tcode{3}. \end{example} The optional \grammarterm{attribute-specifier-seq} in an \grammarterm{enumerator} appertains to that enumerator. \pnum An \grammarterm{opaque-enum-declaration} is either a redeclaration of an enumeration in the current scope or a declaration of a new enumeration. \begin{note} An enumeration declared by an \grammarterm{opaque-enum-declaration} has a fixed underlying type and is a complete type. The list of enumerators can be provided in a later redeclaration with an \grammarterm{enum-specifier}. \end{note} A scoped enumeration shall not be later redeclared as unscoped or with a different underlying type. An unscoped enumeration shall not be later redeclared as scoped and each redeclaration shall include an \grammarterm{enum-base} specifying the same underlying type as in the original declaration. \pnum If an \grammarterm{enum-head-name} contains a \grammarterm{nested-name-specifier}, the enclosing \grammarterm{enum-specifier} or \grammarterm{opaque-enum-declaration} $D$ shall not inhabit a class scope and shall correspond to one or more declarations nominable in the class, class template, or namespace to which the \grammarterm{nested-name-specifier} refers\iref{basic.scope.scope}. All those declarations shall have the same target scope; the target scope of $D$ is that scope. \pnum \indextext{\idxcode{enum}!type of}% \indextext{\idxcode{enum}!underlying type|see{type, underlying}}% Each enumeration defines a type that is different from all other types. Each enumeration also has an \defnx{underlying type}{type!underlying!enumeration}. The underlying type can be explicitly specified using an \grammarterm{enum-base}. For a scoped enumeration type, the underlying type is \tcode{int} if it is not explicitly specified. In both of these cases, the underlying type is said to be \defnx{fixed}{type!underlying!fixed}. Following the closing brace of an \grammarterm{enum-specifier}, each enumerator has the type of its enumeration. If the underlying type is fixed, the type of each enumerator prior to the closing brace is the underlying type and the \grammarterm{constant-expression} in the \grammarterm{enumerator-definition} shall be a converted constant expression of the underlying type\iref{expr.const}. If the underlying type is not fixed, the type of each enumerator prior to the closing brace is determined as follows: \begin{itemize} \item If an initializer is specified for an enumerator, the \grammarterm{constant-expression} shall be an integral constant expression\iref{expr.const}. If the expression has unscoped enumeration type, the enumerator has the underlying type of that enumeration type, otherwise it has the same type as the expression. \item If no initializer is specified for the first enumerator, its type is an unspecified signed integral type. \item Otherwise the type of the enumerator is the same as that of the preceding enumerator unless the incremented value is not representable in that type, in which case the type is an unspecified integral type sufficient to contain the incremented value. If no such type exists, the program is ill-formed. \end{itemize} \pnum An enumeration whose underlying type is fixed is an incomplete type until immediately after its \grammarterm{enum-base} (if any), at which point it becomes a complete type. An enumeration whose underlying type is not fixed is an incomplete type until the closing \tcode{\}} of its \grammarterm{enum-specifier}, at which point it becomes a complete type. \pnum For an enumeration whose underlying type is not fixed, the underlying type is an integral type that can represent all the enumerator values defined in the enumeration. If no integral type can represent all the enumerator values, the enumeration is ill-formed. It is \impldef{underlying type for enumeration} which integral type is used as the underlying type except that the underlying type shall not be larger than \tcode{int} unless the value of an enumerator cannot fit in an \tcode{int} or \tcode{unsigned int}. If the \grammarterm{enumerator-list} is empty, the underlying type is as if the enumeration had a single enumerator with value 0. \pnum \indextext{signed integer representation!two's complement}% For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type. Otherwise, the values of the enumeration are the values representable by a hypothetical integer type with minimal width $M$ such that all enumerators can be represented. The width of the smallest bit-field large enough to hold all the values of the enumeration type is $M$. It is possible to define an enumeration that has values not defined by any of its enumerators. If the \grammarterm{enumerator-list} is empty, the values of the enumeration are as if the enumeration had a single enumerator with value 0. \begin{footnote} This set of values is used to define promotion and conversion semantics for the enumeration type. It does not preclude an expression of enumeration type from having a value that falls outside this range. \end{footnote} \pnum An enumeration has the same size, value representation, and alignment requirements\iref{basic.align} as its underlying type. Furthermore, each value of an enumeration has the same representation as the corresponding value of the underlying type. \pnum Two enumeration types are \defnx{layout-compatible enumerations}{layout-compatible!enumeration} if they have the same underlying type. \pnum The value of an enumerator or an object of an unscoped enumeration type is converted to an integer by integral promotion\iref{conv.prom}. \begin{example} \begin{codeblock} enum color { red, yellow, green=20, blue }; color col = red; color* cp = &col; if (*cp == blue) // ... \end{codeblock} makes \tcode{color} a type describing various colors, and then declares \tcode{col} as an object of that type, and \tcode{cp} as a pointer to an object of that type. The possible values of an object of type \tcode{color} are \tcode{red}, \tcode{yellow}, \tcode{green}, \tcode{blue}; these values can be converted to the integral values \tcode{0}, \tcode{1}, \tcode{20}, and \tcode{21}. Since enumerations are distinct types, objects of type \tcode{color} can be assigned only values of type \tcode{color}. \begin{codeblock} color c = 1; // error: type mismatch, no conversion from \tcode{int} to \tcode{color} int i = yellow; // OK, \tcode{yellow} converted to integral value \tcode{1}, integral promotion \end{codeblock} Note that this implicit \keyword{enum} to \tcode{int} conversion is not provided for a scoped enumeration: \begin{codeblock} enum class Col { red, yellow, green }; int x = Col::red; // error: no \tcode{Col} to \tcode{int} conversion Col y = Col::red; if (y) { } // error: no \tcode{Col} to \tcode{bool} conversion \end{codeblock} \end{example} \pnum \indextext{class!scope of enumerator}% The name of each unscoped enumerator is also bound in the scope that immediately contains the \grammarterm{enum-specifier}. An unnamed enumeration that does not have a typedef name for linkage purposes\iref{dcl.typedef} and that has a first enumerator is denoted, for linkage purposes\iref{basic.link}, by its underlying type and its first enumerator; such an enumeration is said to have an enumerator as a name for linkage purposes. \begin{note} Each unnamed enumeration with no enumerators is a distinct type. \end{note} \begin{example} \begin{codeblock} enum direction { left='l', right='r' }; void g() { direction d; // OK d = left; // OK d = direction::right; // OK } enum class altitude { high='h', low='l' }; void h() { altitude a; // OK a = high; // error: \tcode{high} not in scope a = altitude::low; // OK } \end{codeblock} \end{example} \rSec2[enum.udecl]{The \tcode{using enum} declaration}% \indextext{enumeration!using declaration}% \begin{bnf} \nontermdef{using-enum-declaration}\br \keyword{using} \keyword{enum} using-enum-declarator \terminal{;} \end{bnf} \begin{bnf} \nontermdef{using-enum-declarator}\br \opt{nested-name-specifier} identifier\br \opt{nested-name-specifier} simple-template-id \end{bnf} \pnum A \grammarterm{using-enum-declarator} names the set of declarations found by lookup\iref{basic.lookup.unqual,basic.lookup.qual} for the \grammarterm{using-enum-declarator}. The \grammarterm{using-enum-declarator} shall designate a non-dependent type with a reachable \grammarterm{enum-specifier}. \pnum A \grammarterm{using-enum-declaration} is equivalent to a \grammarterm{using-declaration} for each enumerator. \pnum \begin{note} A \grammarterm{using-enum-declaration} in class scope makes the enumerators of the named enumeration available via member lookup. \begin{example} \begin{codeblock} enum class fruit { orange, apple }; struct S { using enum fruit; // OK, introduces \tcode{orange} and \tcode{apple} into \tcode{S} }; void f() { S s; s.orange; // OK, names \tcode{fruit::orange} S::orange; // OK, names \tcode{fruit::orange} } \end{codeblock} \end{example} \end{note} \pnum \begin{note} Two \grammarterm{using-enum-declaration}s that introduce two enumerators of the same name conflict. \begin{example} \begin{codeblock} enum class fruit { orange, apple }; enum class color { red, orange }; void f() { using enum fruit; // OK using enum color; // error: \tcode{color::orange} and \tcode{fruit::orange} conflict } \end{codeblock} \end{example} \end{note} \rSec1[basic.namespace]{Namespaces}% \rSec2[basic.namespace.general]{General}% \indextext{namespaces|(} \pnum A namespace is an optionally-named entity whose scope can contain declarations of any kind of entity. The name of a namespace can be used to access entities that belong to that namespace; that is, the \defnx{members}{member!namespace} of the namespace. Unlike other entities, the definition of a namespace can be split over several parts of one or more translation units and modules. \pnum \begin{note} A \grammarterm{namespace-definition} is exported if it contains any \grammarterm{export-declaration}{s}\iref{module.interface}. A namespace is never attached to a named module and never has a name with module linkage. \end{note} \begin{example} \begin{codeblock} export module M; namespace N1 {} // \tcode{N1} is not exported export namespace N2 {} // \tcode{N2} is exported namespace N3 { export int n; } // \tcode{N3} is exported \end{codeblock} \end{example} \pnum There is a \defnadj{global}{namespace} with no declaration; see~\ref{basic.scope.namespace}. The global namespace belongs to the global scope; it is not an unnamed namespace\iref{namespace.unnamed}. \begin{note} Lacking a declaration, it cannot be found by name lookup. \end{note} \rSec2[namespace.def]{Namespace definition}% \rSec3[namespace.def.general]{General}% \indextext{definition!namespace}% \indextext{namespace!definition} \begin{bnf} \nontermdef{namespace-name}\br identifier\br namespace-alias \end{bnf} \begin{bnf} \nontermdef{namespace-definition}\br named-namespace-definition\br unnamed-namespace-definition\br nested-namespace-definition \end{bnf} \begin{bnf} \nontermdef{named-namespace-definition}\br \opt{\keyword{inline}} \keyword{namespace} \opt{attribute-specifier-seq} identifier \terminal{\{} namespace-body \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{unnamed-namespace-definition}\br \opt{\keyword{inline}} \keyword{namespace} \opt{attribute-specifier-seq} \terminal{\{} namespace-body \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{nested-namespace-definition}\br \keyword{namespace} enclosing-namespace-specifier \terminal{::} \opt{\keyword{inline}} identifier \terminal{\{} namespace-body \terminal{\}} \end{bnf} \begin{bnf} \nontermdef{enclosing-namespace-specifier}\br identifier\br enclosing-namespace-specifier \terminal{::} \opt{\keyword{inline}} identifier \end{bnf} \begin{bnf} \nontermdef{namespace-body}\br \opt{declaration-seq} \end{bnf} \pnum Every \grammarterm{namespace-definition} shall inhabit a namespace scope\iref{basic.scope.namespace}. \pnum In a \grammarterm{named-namespace-definition} $D$, the \grammarterm{identifier} is the name of the namespace. The \grammarterm{identifier} is looked up by searching for it in the scopes of the namespace $A$ in which $D$ appears and of every element of the inline namespace set of $A$. If the lookup finds a \grammarterm{namespace-definition} for a namespace $N$, \indextext{extend|see{namespace, extend}}% $D$ \defnx{extends}{namespace!extend} $N$, and the target scope of $D$ is the scope to which $N$ belongs. If the lookup finds nothing, the \grammarterm{identifier} is introduced as a \grammarterm{namespace-name} into $A$. \pnum Because a \grammarterm{namespace-definition} contains \grammarterm{declaration}{s} in its \grammarterm{namespace-body} and a \grammarterm{namespace-definition} is itself a \grammarterm{declaration}, it follows that \grammarterm{namespace-definition}{s} can be nested. \begin{example} \begin{codeblock} namespace Outer { int i; namespace Inner { void f() { i++; } // \tcode{Outer::i} int i; void g() { i++; } // \tcode{Inner::i} } } \end{codeblock} \end{example} \pnum If the optional initial \keyword{inline} keyword appears in a \grammarterm{namespace-definition} for a particular namespace, that namespace is declared to be an \defnadj{inline}{namespace}. The \keyword{inline} keyword may be used on a \grammarterm{namespace-definition} that extends a namespace only if it was previously used on the \grammarterm{namespace-definition} that initially declared the \grammarterm{namespace-name} for that namespace. \pnum The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{named-namespace-definition} appertains to the namespace being defined or extended. \pnum Members of an inline namespace can be used in most respects as though they were members of the innermost enclosing namespace. Specifically, the inline namespace and its enclosing namespace are both added to the set of associated namespaces used in argument-dependent lookup\iref{basic.lookup.argdep} whenever one of them is, and a \grammarterm{using-directive}\iref{namespace.udir} that names the inline namespace is implicitly inserted into the enclosing namespace as for an unnamed namespace\iref{namespace.unnamed}. Furthermore, each member of the inline namespace can subsequently be partially specialized\iref{temp.spec.partial}, explicitly instantiated\iref{temp.explicit}, or explicitly specialized\iref{temp.expl.spec} as though it were a member of the enclosing namespace. Finally, looking up a name in the enclosing namespace via explicit qualification\iref{namespace.qual} will include members of the inline namespace even if there are declarations of that name in the enclosing namespace. \pnum These properties are transitive: if a namespace \tcode{N} contains an inline namespace \tcode{M}, which in turn contains an inline namespace \tcode{O}, then the members of \tcode{O} can be used as though they were members of \tcode{M} or \tcode{N}. The \defn{inline namespace set} of \tcode{N} is the transitive closure of all inline namespaces in \tcode{N}. \pnum A \grammarterm{nested-namespace-definition} with an \grammarterm{enclosing-namespace-specifier} \tcode{E}, \grammarterm{identifier} \tcode{I} and \grammarterm{namespace-body} \tcode{B} is equivalent to \begin{codeblock} namespace E { @\opt{inline}@ namespace I { B } } \end{codeblock} where the optional \keyword{inline} is present if and only if the \grammarterm{identifier} \tcode{I} is preceded by \keyword{inline}. \begin{example} \begin{codeblock} namespace A::inline B::C { int i; } \end{codeblock} The above has the same effect as: \begin{codeblock} namespace A { inline namespace B { namespace C { int i; } } } \end{codeblock} \end{example} \rSec3[namespace.unnamed]{Unnamed namespaces}% \indextext{namespace!unnamed} \pnum An \grammarterm{unnamed-namespace-definition} behaves as if it were replaced by \begin{ncsimplebnf} \opt{\keyword{inline}} \keyword{namespace} \exposid{unique} \terminal{\{} \terminal{/* empty body */} \terminal{\}}\br \keyword{using} \keyword{namespace} \exposid{unique} \terminal{;}\br \keyword{namespace} \exposid{unique} \terminal{\{} namespace-body \terminal{\}} \end{ncsimplebnf} where \keyword{inline} appears if and only if it appears in the \grammarterm{unnamed-namespace-definition} and all occurrences of \exposid{unique} in a translation unit are replaced by the same identifier, and this identifier differs from all other identifiers in the translation unit. The optional \grammarterm{attribute-specifier-seq} in the \grammarterm{unnamed-namespace-definition} appertains to \exposid{unique}. \begin{example} \begin{codeblock} namespace { int i; } // \tcode{\exposid{unique}::i} void f() { i++; } // \tcode{\exposid{unique}::i++} namespace A { namespace { int i; // \tcode{A::\exposid{unique}::i} int j; // \tcode{A::\exposid{unique}::j} } void g() { i++; } // \tcode{A::\exposid{unique}::i++} } using namespace A; void h() { i++; // error: \tcode{\exposid{unique}::i} or \tcode{A::\exposid{unique}::i} A::i++; // \tcode{A::\exposid{unique}::i} j++; // \tcode{A::\exposid{unique}::j} } \end{codeblock} \end{example} \rSec2[namespace.alias]{Namespace alias}% \indextext{namespace!alias}% \indextext{alias!namespace}% \indextext{synonym} \pnum A \grammarterm{namespace-alias-definition} declares an alternate name for a namespace according to the following grammar: \begin{bnf} \nontermdef{namespace-alias}\br identifier \end{bnf} \begin{bnf} \nontermdef{namespace-alias-definition}\br \keyword{namespace} identifier \terminal{=} qualified-namespace-specifier \terminal{;} \end{bnf} \begin{bnf} \nontermdef{qualified-namespace-specifier}\br \opt{nested-name-specifier} namespace-name \end{bnf} \pnum The \grammarterm{identifier} in a \grammarterm{namespace-alias-definition} becomes a \grammarterm{namespace-alias} and denotes the namespace denoted by the \grammarterm{qualified-namespace-specifier}. \begin{note} When looking up a \grammarterm{namespace-name} in a \grammarterm{namespace-alias-definition}, only namespace names are considered, see~\ref{basic.lookup.udir}. \end{note} \rSec2[namespace.udir]{Using namespace directive}% \indextext{using-directive|(} \begin{bnf} \nontermdef{using-directive}\br \opt{attribute-specifier-seq} \keyword{using} \keyword{namespace} \opt{nested-name-specifier} namespace-name \terminal{;} \end{bnf} \pnum A \grammarterm{using-directive} shall not appear in class scope, but may appear in namespace scope or in block scope. \begin{note} When looking up a \grammarterm{namespace-name} in a \grammarterm{using-directive}, only namespace names are considered, see~\ref{basic.lookup.udir}. \end{note} The optional \grammarterm{attribute-specifier-seq} appertains to the \grammarterm{using-directive}. \pnum \begin{note} A \grammarterm{using-directive} makes the names in the nominated namespace usable in the scope in which the \grammarterm{using-directive} appears after the \grammarterm{using-directive}\iref{basic.lookup.unqual,namespace.qual}. During unqualified name lookup, the names appear as if they were declared in the nearest enclosing namespace which contains both the \grammarterm{using-directive} and the nominated namespace. \end{note} \pnum \begin{note} A \grammarterm{using-directive} does not introduce any names. \end{note} \begin{example} \begin{codeblock} namespace A { int i; namespace B { namespace C { int i; } using namespace A::B::C; void f1() { i = 5; // OK, \tcode{C::i} visible in \tcode{B} and hides \tcode{A::i} } } namespace D { using namespace B; using namespace C; void f2() { i = 5; // ambiguous, \tcode{B::C::i} or \tcode{A::i}? } } void f3() { i = 5; // uses \tcode{A::i} } } void f4() { i = 5; // error: neither \tcode{i} is visible } \end{codeblock} \end{example} \pnum \begin{note} A \grammarterm{using-directive} is transitive: if a scope contains a \grammarterm{using-directive} that nominates a namespace that itself contains \grammarterm{using-directive}{s}, the namespaces nominated by those \grammarterm{using-directive}{s} are also eligible to be considered. \end{note} \begin{example} \begin{codeblock} namespace M { int i; } namespace N { int i; using namespace M; } void f() { using namespace N; i = 7; // error: both \tcode{M::i} and \tcode{N::i} are visible } \end{codeblock} For another example, \begin{codeblock} namespace A { int i; } namespace B { int i; int j; namespace C { namespace D { using namespace A; int j; int k; int a = i; // \tcode{B::i} hides \tcode{A::i} } using namespace D; int k = 89; // no problem yet int l = k; // ambiguous: \tcode{C::k} or \tcode{D::k} int m = i; // \tcode{B::i} hides \tcode{A::i} int n = j; // \tcode{D::j} hides \tcode{B::j} } } \end{codeblock} \end{example} \pnum \begin{note} Declarations in a namespace that appear after a \grammarterm{using-directive} for that namespace can be found through that \grammarterm{using-directive} after they appear. \end{note} \pnum \begin{note} If name lookup finds a declaration for a name in two different namespaces, and the declarations do not declare the same entity and do not declare functions or function templates, the use of the name is ill-formed\iref{basic.lookup}. In particular, the name of a variable, function or enumerator does not hide the name of a class or enumeration declared in a different namespace. For example, \begin{codeblock} namespace A { class X { }; extern "C" int g(); extern "C++" int h(); } namespace B { void X(int); extern "C" int g(); extern "C++" int h(int); } using namespace A; using namespace B; void f() { X(1); // error: name \tcode{X} found in two namespaces g(); // OK, name \tcode{g} refers to the same entity h(); // OK, overload resolution selects \tcode{A::h} } \end{codeblock} \end{note} \pnum \indextext{overloading!using directive and}% \begin{note} The order in which namespaces are considered and the relationships among the namespaces implied by the \grammarterm{using-directive}{s} do not affect overload resolution. Neither is any function excluded because another has the same signature, even if one is in a namespace reachable through \grammarterm{using-directive}{s} in the namespace of the other. \begin{footnote} During name lookup in a class hierarchy, some ambiguities can be resolved by considering whether one member hides the other along some paths\iref{class.member.lookup}. There is no such disambiguation when considering the set of names found as a result of following \grammarterm{using-directive}{s}. \end{footnote} \end{note} \begin{example} \begin{codeblock} namespace D { int d1; void f(char); } using namespace D; int d1; // OK, no conflict with \tcode{D::d1} namespace E { int e; void f(int); } namespace D { // namespace extension int d2; using namespace E; void f(int); } void f() { d1++; // error: ambiguous \tcode{::d1} or \tcode{D::d1}? ::d1++; // OK D::d1++; // OK d2++; // OK, \tcode{D::d2} e++; // OK, \tcode{E::e} f(1); // error: ambiguous: \tcode{D::f(int)} or \tcode{E::f(int)}? f('a'); // OK, \tcode{D::f(char)} } \end{codeblock} \end{example} \indextext{using-directive|)}% \indextext{namespaces|)} \rSec1[namespace.udecl]{The \tcode{using} declaration}% \indextext{using-declaration|(} \begin{bnf} \nontermdef{using-declaration}\br \keyword{using} using-declarator-list \terminal{;} \end{bnf} \begin{bnf} \nontermdef{using-declarator-list}\br using-declarator \opt{\terminal{...}}\br using-declarator-list \terminal{,} using-declarator \opt{\terminal{...}} \end{bnf} \begin{bnf} \nontermdef{using-declarator}\br \opt{\keyword{typename}} nested-name-specifier unqualified-id \end{bnf} \pnum \indextext{component name}% The component names of a \grammarterm{using-declarator} are those of its \grammarterm{nested-name-specifier} and \grammarterm{unqualified-id}. Each \grammarterm{using-declarator} in a \grammarterm{using-declaration} \begin{footnote} A \grammarterm{using-declaration} with more than one \grammarterm{using-declarator} is equivalent to a corresponding sequence of \grammarterm{using-declaration}{s} with one \grammarterm{using-declarator} each. \end{footnote} names the set of declarations found by lookup\iref{basic.lookup.qual} for the \grammarterm{using-declarator}, except that class and enumeration declarations that would be discarded are merely ignored when checking for ambiguity\iref{basic.lookup}, conversion function templates with a dependent return type are ignored, and certain functions are hidden as described below. If the terminal name of the \grammarterm{using-declarator} is dependent\iref{temp.dep.type}, the \grammarterm{using-declarator} is considered to name a constructor if and only if the \grammarterm{nested-name-specifier} has a terminal name that is the same as the \grammarterm{unqualified-id}. If the lookup in any instantiation finds that a \grammarterm{using-declarator} that is not considered to name a constructor does do so, or that a \grammarterm{using-declarator} that is considered to name a constructor does not, the program is ill-formed. \pnum \indextext{inheritance!\idxgram{using-declaration} and}% If the \grammarterm{using-declarator} names a constructor, it declares that the class \defnx{inherits}{constructor!inherited} the named set of constructor declarations from the nominated base class. \begin{note} Otherwise, the \grammarterm{unqualified-id} in the \grammarterm{using-declarator} is bound to the \grammarterm{using-declarator}, which is replaced during name lookup with the declarations it names\iref{basic.lookup}. If such a declaration is of an enumeration, the names of its enumerators are not bound. For the keyword \keyword{typename}, see \ref{temp.res}. \end{note} \pnum In a \grammarterm{using-declaration} used as a \grammarterm{member-declaration}, each \grammarterm{using-declarator} shall either name an enumerator or have a \grammarterm{nested-name-specifier} naming a base class of the current class\iref{expr.prim.this}. \begin{example} \begin{codeblock} enum class button { up, down }; struct S { using button::up; button b = up; // OK }; \end{codeblock} \end{example} If a \grammarterm{using-declarator} names a constructor, its \grammarterm{nested-name-specifier} shall name a direct base class of the current class. If the immediate (class) scope is associated with a class template, it shall derive from the specified base class or have at least one dependent base class. \begin{example} \begin{codeblock} struct B { void f(char); enum E { e }; union { int x; }; }; struct C { int f(); }; struct D : B { using B::f; // OK, \tcode{B} is a base of \tcode{D} using B::e; // OK, \tcode{e} is an enumerator of base \tcode{B} using B::x; // OK, \tcode{x} is a union member of base \tcode{B} using C::f; // error: \tcode{C} isn't a base of \tcode{D} void f(int) { f('c'); } // calls \tcode{B::f(char)} void g(int) { g('c'); } // recursively calls \tcode{D::g(int)} }; template struct X : bases... { using bases::f...; }; X x; // OK, \tcode{B::f} and \tcode{C::f} named \end{codeblock} \end{example} \pnum \begin{note} Since destructors do not have names, a \grammarterm{using-declaration} cannot refer to a destructor for a base class. \end{note} If a constructor or assignment operator brought from a base class into a derived class has the signature of a copy/move constructor or assignment operator for the derived class\iref{class.copy.ctor,class.copy.assign}, the \grammarterm{using-declaration} does not by itself suppress the implicit declaration of the derived class member; the member from the base class is hidden or overridden by the implicitly-declared copy/move constructor or assignment operator of the derived class, as described below. \pnum A \grammarterm{using-declaration} shall not name a \grammarterm{template-id}. \begin{example} \begin{codeblock} struct A { template void f(T); template struct X { }; }; struct B : A { using A::f; // error using A::X; // error }; \end{codeblock} \end{example} \pnum A \grammarterm{using-declaration} shall not name a namespace. \pnum A \grammarterm{using-declaration} that names a class member other than an enumerator shall be a \grammarterm{member-declaration}. \begin{example} \begin{codeblock} struct X { int i; static int s; }; void f() { using X::i; // error: \tcode{X::i} is a class member and this is not a member declaration. using X::s; // error: \tcode{X::s} is a class member and this is not a member declaration. } \end{codeblock} \end{example} \pnum If a declaration is named by two \grammarterm{using-declarator}s that inhabit the same class scope, the program is ill-formed. \pnum \begin{note} A \grammarterm{using-declarator} whose \grammarterm{nested-name-specifier} names a namespace does not name declarations added to the namespace after it. Thus, additional overloads added after the \grammarterm{using-declaration} are ignored, but default function arguments\iref{dcl.fct.default}, default template arguments\iref{temp.param}, and template specializations\iref{temp.spec.partial,temp.expl.spec} are considered. \end{note} \begin{example} \begin{codeblock} namespace A { void f(int); } using A::f; // \tcode{f} is a synonym for \tcode{A::f}; that is, for \tcode{A::f(int)}. namespace A { void f(char); } void foo() { f('a'); // calls \tcode{f(int)}, even though \tcode{f(char)} exists. } void bar() { using A::f; // \tcode{f} is a synonym for \tcode{A::f}; that is, for \tcode{A::f(int)} and \tcode{A::f(char)}. f('a'); // calls \tcode{f(char)} } \end{codeblock} \end{example} \pnum If a declaration named by a \grammarterm{using-declaration} that inhabits the target scope of another declaration potentially conflicts with it\iref{basic.scope.scope}, and either is reachable from the other, the program is ill-formed. If two declarations named by \grammarterm{using-declaration}s that inhabit the same scope potentially conflict, either is reachable from the other, and they do not both declare functions or function templates, the program is ill-formed. \begin{note} Overload resolution possibly cannot distinguish between conflicting function declarations. \end{note} \begin{example} \begin{codeblock} namespace A { int x; int f(int); int g; void h(); } namespace B { int i; struct g { }; struct x { }; void f(int); void f(double); void g(char); // OK, hides \tcode{struct g} } void func() { int i; using B::i; // error: conflicts void f(char); using B::f; // OK, each \tcode{f} is a function using A::f; // OK, but interferes with \tcode{B::f(int)} f(1); // error: ambiguous static_cast(f)(1); // OK, calls \tcode{A::f} f(3.5); // calls \tcode{B::f(double)} using B::g; g('a'); // calls \tcode{B::g(char)} struct g g1; // \tcode{g1} has class type \tcode{B::g} using A::g; // error: conflicts with \tcode{B::g} void h(); using A::h; // error: conflicts using B::x; using A::x; // OK, hides \tcode{struct B::x} x = 99; // assigns to \tcode{A::x} struct x x1; // \tcode{x1} has class type \tcode{B::x} } \end{codeblock} \end{example} \pnum \indextext{name hiding!using-declaration and}% The set of declarations named by a \grammarterm{using-declarator} that inhabits a class \tcode{C} does not include member functions and member function templates of a base class that correspond to (and thus would conflict with) a declaration of a function or function template in \tcode{C}. \begin{example} \begin{codeblock} struct B { virtual void f(int); virtual void f(char); void g(int); void h(int); }; struct D : B { using B::f; void f(int); // OK, \tcode{D::f(int)} overrides \tcode{B::f(int)}; using B::g; void g(char); // OK using B::h; void h(int); // OK, \tcode{D::h(int)} hides \tcode{B::h(int)} }; void k(D* p) { p->f(1); // calls \tcode{D::f(int)} p->f('a'); // calls \tcode{B::f(char)} p->g(1); // calls \tcode{B::g(int)} p->g('a'); // calls \tcode{D::g(char)} } struct B1 { B1(int); }; struct B2 { B2(int); }; struct D1 : B1, B2 { using B1::B1; using B2::B2; }; D1 d1(0); // error: ambiguous struct D2 : B1, B2 { using B1::B1; using B2::B2; D2(int); // OK, \tcode{D2::D2(int)} hides \tcode{B1::B1(int)} and \tcode{B2::B2(int)} }; D2 d2(0); // calls \tcode{D2::D2(int)} \end{codeblock} \end{example} \pnum \indextext{overloading!using-declaration and}% \begin{note} For the purpose of forming a set of candidates during overload resolution, the functions named by a \grammarterm{using-declaration} in a derived class are treated as though they were direct members of the derived class. In particular, the implicit object parameter is treated as if it were a reference to the derived class rather than to the base class\iref{over.match.funcs}. This has no effect on the type of the function, and in all other respects the function remains part of the base class. \end{note} \pnum Constructors that are named by a \grammarterm{using-declaration} are treated as though they were constructors of the derived class when looking up the constructors of the derived class\iref{class.qual} or forming a set of overload candidates\iref{over.match.ctor,over.match.copy,over.match.list}. \begin{note} If such a constructor is selected to perform the initialization of an object of class type, all subobjects other than the base class from which the constructor originated are implicitly initialized\iref{class.inhctor.init}. A constructor of a derived class is sometimes preferred to a constructor of a base class if they would otherwise be ambiguous\iref{over.match.best}. \end{note} \pnum \indextext{access control!using-declaration and}% In a \grammarterm{using-declarator} that does not name a constructor, every declaration named shall be accessible. In a \grammarterm{using-declarator} that names a constructor, no access check is performed. \pnum \begin{note} Because a \grammarterm{using-declarator} designates a base class member (and not a member subobject or a member function of a base class subobject), a \grammarterm{using-declarator} cannot be used to resolve inherited member ambiguities. \begin{example} \begin{codeblock} struct A { int x(); }; struct B : A { }; struct C : A { using A::x; int x(int); }; struct D : B, C { using C::x; int x(double); }; int f(D* d) { return d->x(); // error: overload resolution selects \tcode{A::x}, but \tcode{A} is an ambiguous base class } \end{codeblock} \end{example} \end{note} \pnum A \grammarterm{using-declaration} has the usual accessibility for a \grammarterm{member-declaration}. Base-class constructors considered because of a \grammarterm{using-declarator} are accessible if they would be accessible when used to construct an object of the base class; the accessibility of the \grammarterm{using-declaration} is ignored. \begin{example} \begin{codeblock} class A { private: void f(char); public: void f(int); protected: void g(); }; class B : public A { using A::f; // error: \tcode{A::f(char)} is inaccessible public: using A::g; // \tcode{B::g} is a public synonym for \tcode{A::g} }; \end{codeblock} \end{example} \indextext{using-declaration|)} \rSec1[dcl.asm]{The \tcode{asm} declaration}% \indextext{declaration!\idxcode{asm}}% \indextext{assembler}% \indextext{\idxcode{asm}!implementation-defined} \pnum An \tcode{asm} declaration has the form \begin{bnf} \nontermdef{asm-declaration}\br \opt{attribute-specifier-seq} \keyword{asm} \terminal{(} string-literal \terminal{)} \terminal{;} \end{bnf} The \tcode{asm} declaration is conditionally-supported; its meaning is \impldef{meaning of \tcode{asm} declaration}. The optional \grammarterm{attribute-specifier-seq} in an \grammarterm{asm-declaration} appertains to the \tcode{asm} declaration. \begin{note} Typically it is used to pass information through the implementation to an assembler. \end{note} \rSec1[dcl.link]{Linkage specifications}% \indextext{specification!linkage|(} \pnum All functions and variables whose names have external linkage and all function types have a \defn{language linkage}. \begin{note} Some of the properties associated with an entity with language linkage are specific to each implementation and are not described here. For example, a particular language linkage might be associated with a particular form of representing names of objects and functions with external linkage, or with a particular calling convention, etc. \end{note} The default language linkage of all function types, functions, and variables is \Cpp{} language linkage. Two function types with different language linkages are distinct types even if they are otherwise identical. \pnum Linkage\iref{basic.link} between \Cpp{} and non-\Cpp{} code fragments can be achieved using a \grammarterm{linkage-specification}: \indextext{\idxgram{linkage-specification}}% \indextext{specification!linkage!\idxcode{extern}}% % \begin{bnf} \nontermdef{linkage-specification}\br \keyword{extern} string-literal \terminal{\{} \opt{declaration-seq} \terminal{\}}\br \keyword{extern} string-literal name-declaration \end{bnf} The \grammarterm{string-literal} indicates the required language linkage. This document specifies the semantics for the \grammarterm{string-literal}{s} \tcode{"C"} and \tcode{"C++"}. Use of a \grammarterm{string-literal} other than \tcode{"C"} or \tcode{"C++"} is conditionally-supported, with \impldef{semantics of linkage specifiers} semantics. \begin{note} Therefore, a linkage-specification with a \grammarterm{string-literal} that is unknown to the implementation requires a diagnostic. \end{note} \recommended The spelling of the \grammarterm{string-literal} should be taken from the document defining that language. For example, \tcode{Ada} (not \tcode{ADA}) and \tcode{Fortran} or \tcode{FORTRAN}, depending on the vintage. \pnum \indextext{specification!linkage!implementation-defined}% Every implementation shall provide for linkage to the C programming language, \indextext{C!linkage to}% \tcode{"C"}, and \Cpp{}, \tcode{"C++"}. \begin{example} \begin{codeblock} complex sqrt(complex); // \Cpp{} language linkage by default extern "C" { double sqrt(double); // C language linkage } \end{codeblock} \end{example} \pnum A \grammarterm{module-import-declaration} appearing in a linkage specification with other than \Cpp{} language linkage is conditionally-supported with \impldef{support for \grammarterm{module-import-declaration}s with non-\Cpp{} language linkage} semantics. \pnum \indextext{specification!linkage!nesting}% Linkage specifications nest. When linkage specifications nest, the innermost one determines the language linkage. \begin{note} A linkage specification does not establish a scope. \end{note} A \grammarterm{linkage-specification} shall inhabit a namespace scope. In a \grammarterm{linkage-specification}, the specified language linkage applies to the function types of all function declarators and to all functions and variables whose names have external linkage. \begin{example} \begin{codeblock} extern "C" // \tcode{f1} and its function type have C language linkage; void f1(void(*pf)(int)); // \tcode{pf} is a pointer to a C function extern "C" typedef void FUNC(); FUNC f2; // \tcode{f2} has \Cpp{} language linkage and // its type has C language linkage extern "C" FUNC f3; // \tcode{f3} and its type have C language linkage void (*pf2)(FUNC*); // the variable \tcode{pf2} has \Cpp{} language linkage; its type // is ``pointer to \Cpp{} function that takes one parameter of type // pointer to C function'' extern "C" { static void f4(); // the name of the function \tcode{f4} has internal linkage, // so \tcode{f4} has no language linkage; its type has C language linkage } extern "C" void f5() { extern void f4(); // OK, name linkage (internal) and function type linkage (C language linkage) // obtained from previous declaration. } extern void f4(); // OK, name linkage (internal) and function type linkage (C language linkage) // obtained from previous declaration. void f6() { extern void f4(); // OK, name linkage (internal) and function type linkage (C language linkage) // obtained from previous declaration. } \end{codeblock} \end{example} \indextext{class!linkage specification}% A C language linkage is ignored in determining the language linkage of class members, friend functions with a trailing \grammarterm{requires-clause}, and the function type of non-static class member functions. \begin{example} \begin{codeblock} extern "C" typedef void FUNC_c(); class C { void mf1(FUNC_c*); // the function \tcode{mf1} and its type have \Cpp{} language linkage; // the parameter has type ``pointer to C function'' FUNC_c mf2; // the function \tcode{mf2} and its type have \Cpp{} language linkage static FUNC_c* q; // the data member \tcode{q} has \Cpp{} language linkage; // its type is ``pointer to C function'' }; extern "C" { class X { void mf(); // the function \tcode{mf} and its type have \Cpp{} language linkage void mf2(void(*)()); // the function \tcode{mf2} has \Cpp{} language linkage; // the parameter has type ``pointer to C function'' }; } \end{codeblock} \end{example} \pnum If two declarations of an entity give it different language linkages, the program is ill-formed; no diagnostic is required if neither declaration is reachable from the other. \indextext{consistency!linkage specification}% A redeclaration of an entity without a linkage specification inherits the language linkage of the entity and (if applicable) its type. \pnum \indextext{function!linkage specification overloaded}% Two declarations declare the same entity if they (re)introduce the same name, one declares a function or variable with C language linkage, and the other declares such an entity or declares a variable that belongs to the global scope. \begin{example} \begin{codeblock} int x; namespace A { extern "C" int f(); extern "C" int g() { return 1; } extern "C" int h(); extern "C" int x(); // error: same name as global-space object \tcode{x} } namespace B { extern "C" int f(); // \tcode{A::f} and \tcode{B::f} refer to the same function extern "C" int g() { return 1; } // error: the function \tcode{g} with C language linkage has two definitions } int A::f() { return 98; } // definition for the function \tcode{f} with C language linkage extern "C" int h() { return 97; } // definition for the function \tcode{h} with C language linkage // \tcode{A::h} and \tcode{::h} refer to the same function \end{codeblock} \end{example} \pnum A declaration directly contained in a \grammarterm{linkage-specification} is treated as if it contains the \keyword{extern} specifier\iref{dcl.stc} for the purpose of determining the linkage of the declared name and whether it is a definition. Such a declaration shall not specify a storage class. \begin{example} \begin{codeblock} extern "C" double f(); static double f(); // error extern "C" int i; // declaration extern "C" { int i; // definition } extern "C" static void g(); // error \end{codeblock} \end{example} \pnum \begin{note} Because the language linkage is part of a function type, when indirecting through a pointer to C function, the function to which the resulting lvalue refers is considered a C function. \end{note} \pnum \indextext{object!linkage specification}% \indextext{linkage!implementation-defined object}% Linkage from \Cpp{} to objects defined in other languages and to objects defined in \Cpp{} from other languages is \impldef{linkage of objects between \Cpp{} and other languages} and language-dependent. Only where the object layout strategies of two language implementations are similar enough can such linkage be achieved.% \indextext{specification!linkage|)} \rSec1[dcl.attr]{Attributes}% \indextext{attribute|(} \rSec2[dcl.attr.grammar]{Attribute syntax and semantics} \pnum \indextext{attribute!syntax and semantics}% Attributes specify additional information for various source constructs such as types, variables, names, blocks, or translation units. \begin{bnf} \nontermdef{attribute-specifier-seq}\br \opt{attribute-specifier-seq} attribute-specifier \end{bnf} \begin{bnf} \nontermdef{attribute-specifier}\br \terminal{[} \terminal{[} \opt{attribute-using-prefix} attribute-list \terminal{]} \terminal{]}\br alignment-specifier \end{bnf} \begin{bnf} \nontermdef{alignment-specifier}\br \keyword{alignas} \terminal{(} type-id \opt{\terminal{...}} \terminal{)}\br \keyword{alignas} \terminal{(} constant-expression \opt{\terminal{...}} \terminal{)} \end{bnf} \begin{bnf} \nontermdef{attribute-using-prefix}\br \keyword{using} attribute-namespace \terminal{:} \end{bnf} \begin{bnf} \nontermdef{attribute-list}\br \opt{attribute}\br attribute-list \terminal{,} \opt{attribute}\br attribute \terminal{...}\br attribute-list \terminal{,} attribute \terminal{...} \end{bnf} \begin{bnf} \nontermdef{attribute}\br attribute-token \opt{attribute-argument-clause} \end{bnf} \begin{bnf} \nontermdef{attribute-token}\br identifier\br attribute-scoped-token \end{bnf} \begin{bnf} \nontermdef{attribute-scoped-token}\br attribute-namespace \terminal{::} identifier \end{bnf} \begin{bnf} \nontermdef{attribute-namespace}\br identifier \end{bnf} \begin{bnf} \nontermdef{attribute-argument-clause}\br \terminal{(} \opt{balanced-token-seq} \terminal{)} \end{bnf} \begin{bnf} \nontermdef{balanced-token-seq}\br balanced-token\br balanced-token-seq balanced-token \end{bnf} \begin{bnf} \microtypesetup{protrusion=false}\obeyspaces \nontermdef{balanced-token}\br \terminal{(} \opt{balanced-token-seq} \terminal{)}\br \terminal{[} \opt{balanced-token-seq} \terminal{]}\br \terminal{\{} \opt{balanced-token-seq} \terminal{\}}\br \textnormal{any \grammarterm{token} other than a parenthesis, a bracket, or a brace} \end{bnf} \pnum If an \grammarterm{attribute-specifier} contains an \grammarterm{attribute-using-prefix}, the \grammarterm{attribute-list} following that \grammarterm{attribute-using-prefix} shall not contain an \grammarterm{attribute-scoped-token} and every \grammarterm{attribute-token} in that \grammarterm{attribute-list} is treated as if its \grammarterm{identifier} were prefixed with \tcode{N::}, where \tcode{N} is the \grammarterm{attribute-namespace} specified in the \grammarterm{attribute-using-prefix}. \begin{note} This rule imposes no constraints on how an \grammarterm{attribute-using-prefix} affects the tokens in an \grammarterm{attribute-argument-clause}. \end{note} \begin{example} \begin{codeblock} [[using CC: opt(1), debug]] // same as \tcode{[[CC::opt(1), CC::debug]]} void f() {} [[using CC: opt(1)]] [[CC::debug]] // same as \tcode{[[CC::opt(1)]] [[CC::debug]]} void g() {} [[using CC: CC::opt(1)]] // error: cannot combine \tcode{using} and scoped attribute token void h() {} \end{codeblock} \end{example} \pnum \begin{note} For each individual attribute, the form of the \grammarterm{balanced-token-seq} will be specified. \end{note} \pnum In an \grammarterm{attribute-list}, an ellipsis may appear only if that \grammarterm{attribute}'s specification permits it. An \grammarterm{attribute} followed by an ellipsis is a pack expansion\iref{temp.variadic}. An \grammarterm{attribute-specifier} that contains no \grammarterm{attribute}{s} has no effect. The order in which the \grammarterm{attribute-token}{s} appear in an \grammarterm{attribute-list} is not significant. If a keyword\iref{lex.key} or an alternative token\iref{lex.digraph} that satisfies the syntactic requirements of an \grammarterm{identifier}\iref{lex.name} is contained in an \grammarterm{attribute-token}, it is considered an identifier. No name lookup\iref{basic.lookup} is performed on any of the identifiers contained in an \grammarterm{attribute-token}. The \grammarterm{attribute-token} determines additional requirements on the \grammarterm{attribute-argument-clause} (if any). \pnum Each \grammarterm{attribute-specifier-seq} is said to \defn{appertain} to some entity or statement, identified by the syntactic context where it appears\iref{stmt.stmt,dcl.dcl,dcl.decl}. If an \grammarterm{attribute-specifier-seq} that appertains to some entity or statement contains an \grammarterm{attribute} or \grammarterm{alignment-specifier} that is not allowed to apply to that entity or statement, the program is ill-formed. If an \grammarterm{attribute-specifier-seq} appertains to a friend declaration\iref{class.friend}, that declaration shall be a definition. \begin{note} An \grammarterm{attribute-specifier-seq} cannot appeartain to an explicit instantiation\iref{temp.explicit}. \end{note} \pnum For an \grammarterm{attribute-token} (including an \grammarterm{attribute-scoped-token}) not specified in this document, the behavior is \impldef{behavior of non-standard attributes}; any such \grammarterm{attribute-token} that is not recognized by the implementation is ignored. \begin{note} A program is ill-formed if it contains an \grammarterm{attribute} specified in \ref{dcl.attr} that violates the rules specifying to which entity or statement the attribute can apply or the syntax rules for the attribute's \grammarterm{attribute-argument-clause}, if any. \end{note} \begin{note} The \grammarterm{attribute}{s} specified in \ref{dcl.attr} have optional semantics: given a well-formed program, removing all instances of any one of those \grammarterm{attribute}{s} results in a program whose set of possible executions\iref{intro.abstract} for a given input is a subset of those of the original program for the same input, absent implementation-defined guarantees with respect to that \grammarterm{attribute}. \end{note} An \grammarterm{attribute-token} is reserved for future standardization if \begin{itemize} \item it is not an \grammarterm{attribute-scoped-token} and is not specified in this document, or \item it is an \grammarterm{attribute-scoped-token} and its \grammarterm{attribute-namespace} is \tcode{std} followed by zero or more digits. \end{itemize} Each implementation should choose a distinctive name for the \grammarterm{attribute-namespace} in an \grammarterm{attribute-scoped-token}. \pnum Two consecutive left square bracket tokens shall appear only when introducing an \grammarterm{attribute-specifier} or within the \grammarterm{balanced-token-seq} of an \grammarterm{attribute-argument-clause}. \begin{note} If two consecutive left square brackets appear where an \grammarterm{attribute-specifier} is not allowed, the program is ill-formed even if the brackets match an alternative grammar production. \end{note} \begin{example} \begin{codeblock} int p[10]; void f() { int x = 42, y[5]; int(p[[x] { return x; }()]); // error: invalid attribute on a nested \grammarterm{declarator-id} and // not a function-style cast of an element of \tcode{p}. y[[] { return 2; }()] = 2; // error even though attributes are not allowed in this context. int i [[vendor::attr([[]])]]; // well-formed implementation-defined attribute. } \end{codeblock} \end{example} \rSec2[dcl.align]{Alignment specifier}% \indextext{attribute!alignment} \indextext{\idxcode{alignas}} \pnum An \grammarterm{alignment-specifier} may be applied to a variable or to a class data member, but it shall not be applied to a bit-field, a function parameter, or an \grammarterm{exception-declaration}\iref{except.handle}. An \grammarterm{alignment-specifier} may also be applied to the declaration of a class (in an \grammarterm{elaborated-type-specifier}\iref{dcl.type.elab} or \grammarterm{class-head}\iref{class}, respectively). An \grammarterm{alignment-specifier} with an ellipsis is a pack expansion\iref{temp.variadic}. \pnum When the \grammarterm{alignment-specifier} is of the form \tcode{alignas(} \grammarterm{constant-expression} \tcode{)}: \begin{itemize} \item the \grammarterm{constant-expression} shall be an integral constant expression \item if the constant expression does not evaluate to an alignment value\iref{basic.align}, or evaluates to an extended alignment and the implementation does not support that alignment in the context of the declaration, the program is ill-formed. \end{itemize} \pnum An \grammarterm{alignment-specifier} of the form \tcode{alignas(} \grammarterm{type-id} \tcode{)} has the same effect as \tcode{alignas(\brk{}alignof(} \grammarterm{type-id}~\tcode{))}\iref{expr.alignof}. \pnum The alignment requirement of an entity is the strictest nonzero alignment specified by its \grammarterm{alignment-specifier}{s}, if any; otherwise, the \grammarterm{alignment-specifier}{s} have no effect. \pnum The combined effect of all \grammarterm{alignment-specifier}{s} in a declaration shall not specify an alignment that is less strict than the alignment that would be required for the entity being declared if all \grammarterm{alignment-specifier}{s} appertaining to that entity were omitted. \begin{example} \begin{codeblock} struct alignas(8) S {}; struct alignas(1) U { S s; }; // error: \tcode{U} specifies an alignment that is less strict than if the \tcode{alignas(1)} were omitted. \end{codeblock} \end{example} \pnum If the defining declaration of an entity has an \grammarterm{alignment-specifier}{}, any non-defining declaration of that entity shall either specify equivalent alignment or have no \grammarterm{alignment-specifier}{}. Conversely, if any declaration of an entity has an \grammarterm{alignment-specifier}{}, every defining declaration of that entity shall specify an equivalent alignment. No diagnostic is required if declarations of an entity have different \grammarterm{alignment-specifier}{s} in different translation units. \begin{example} \begin{codeblock} // Translation unit \#1: struct S { int x; } s, *p = &s; // Translation unit \#2: struct alignas(16) S; // ill-formed, no diagnostic required: definition of \tcode{S} lacks alignment extern S* p; \end{codeblock} \end{example} \pnum \begin{example} An aligned buffer with an alignment requirement of \tcode{A} and holding \tcode{N} elements of type \tcode{T} can be declared as: \begin{codeblock} alignas(T) alignas(A) T buffer[N]; \end{codeblock} Specifying \tcode{alignas(T)} ensures that the final requested alignment will not be weaker than \tcode{alignof(T)}, and therefore the program will not be ill-formed. \end{example} \pnum \begin{example} \begin{codeblock} alignas(double) void f(); // error: alignment applied to function alignas(double) unsigned char c[sizeof(double)]; // array of characters, suitably aligned for a \tcode{double} extern unsigned char c[sizeof(double)]; // no \tcode{alignas} necessary alignas(float) extern unsigned char c[sizeof(double)]; // error: different alignment in declaration \end{codeblock} \end{example} \rSec2[dcl.attr.assume]{Assumption attribute} The \grammarterm{attribute-token} \tcode{assume} may be applied to a null statement; such a statement is an \defn{assumption}. An \grammarterm{attribute-argument-clause} shall be present and shall have the form: \begin{ncsimplebnf} \terminal{(} conditional-expression \terminal{)} \end{ncsimplebnf} The expression is contextually converted to \tcode{bool}\iref{conv.general}. The expression is not evaluated. If the converted expression would evaluate to \tcode{true} at the point where the assumption appears, the assumption has no effect. Otherwise, the behavior is undefined. \begin{note} The expression is potentially evaluated\iref{basic.def.odr}. The use of assumptions is intended to allow implementations to analyze the form of the expression and deduce information used to optimize the program. Implementations are not required to deduce any information from any particular assumption. \end{note} \begin{example} \begin{codeblock} int divide_by_32(int x) { [[assume(x >= 0)]]; return x/32; // The instructions produced for the division // may omit handling of negative values. } int f(int y) { [[assume(++y == 43)]]; // \tcode{y} is not incremented return y; // statement may be replaced with \tcode{return 42;} } \end{codeblock} \end{example} \rSec2[dcl.attr.depend]{Carries dependency attribute}% \indextext{attribute!carries dependency} \pnum The \grammarterm{attribute-token} \tcode{carries_dependency} specifies dependency propagation into and out of functions. No \grammarterm{attribute-argument-clause} shall be present. The attribute may be applied to a parameter of a function or lambda, in which case it specifies that the initialization of the parameter carries a dependency to\iref{intro.multithread} each lvalue-to-rvalue conversion\iref{conv.lval} of that object. The attribute may also be applied to a function or a lambda call operator, in which case it specifies that the return value, if any, carries a dependency to the evaluation of the function call expression. \pnum The first declaration of a function shall specify the \tcode{carries_dependency} attribute for its \grammarterm{declarator-id} if any declaration of the function specifies the \tcode{carries_dependency} attribute. Furthermore, the first declaration of a function shall specify the \tcode{carries_dependency} attribute for a parameter if any declaration of that function specifies the \tcode{carries_dependency} attribute for that parameter. If a function or one of its parameters is declared with the \tcode{carries_dependency} attribute in its first declaration in one translation unit and the same function or one of its parameters is declared without the \tcode{carries_dependency} attribute in its first declaration in another translation unit, the program is ill-formed, no diagnostic required. \pnum \begin{note} The \tcode{carries_dependency} attribute does not change the meaning of the program, but might result in generation of more efficient code. \end{note} \pnum \begin{example} \begin{codeblock} /* Translation unit A. */ struct foo { int* a; int* b; }; std::atomic foo_head[10]; int foo_array[10][10]; [[carries_dependency]] struct foo* f(int i) { return foo_head[i].load(memory_order::consume); } int g(int* x, int* y [[carries_dependency]]) { return kill_dependency(foo_array[*x][*y]); } /* Translation unit B. */ [[carries_dependency]] struct foo* f(int i); int g(int* x, int* y [[carries_dependency]]); int c = 3; void h(int i) { struct foo* p; p = f(i); do_something_with(g(&c, p->a)); do_something_with(g(p->a, &c)); } \end{codeblock} The \tcode{carries_dependency} attribute on function \tcode{f} means that the return value carries a dependency out of \tcode{f}, so that the implementation need not constrain ordering upon return from \tcode{f}. Implementations of \tcode{f} and its caller may choose to preserve dependencies instead of emitting hardware memory ordering instructions (a.k.a.\ fences). Function \tcode{g}'s second parameter has a \tcode{carries_dependency} attribute, but its first parameter does not. Therefore, function \tcode{h}'s first call to \tcode{g} carries a dependency into \tcode{g}, but its second call does not. The implementation might need to insert a fence prior to the second call to \tcode{g}. \end{example} \indextext{attribute|)}% \indextext{declaration|)} \rSec2[dcl.attr.deprecated]{Deprecated attribute}% \indextext{attribute!deprecated} \pnum The \grammarterm{attribute-token} \tcode{deprecated} can be used to mark names and entities whose use is still allowed, but is discouraged for some reason. \begin{note} In particular, \tcode{deprecated} is appropriate for names and entities that are deemed obsolescent or unsafe. \end{note} An \grammarterm{attribute-argument-clause} may be present and, if present, it shall have the form: \begin{ncbnf} \terminal{(} string-literal \terminal{)} \end{ncbnf} \begin{note} The \grammarterm{string-literal} in the \grammarterm{attribute-argument-clause} can be used to explain the rationale for deprecation and/or to suggest a replacing entity. \end{note} \pnum The attribute may be applied to the declaration of a class, a \grammarterm{typedef-name}, a variable, a non-static data member, a function, a namespace, an enumeration, an enumerator, a concept, or a template specialization. \pnum An entity declared without the \tcode{deprecated} attribute can later be redeclared with the attribute and vice-versa. \begin{note} Thus, an entity initially declared without the attribute can be marked as deprecated by a subsequent redeclaration. However, after an entity is marked as deprecated, later redeclarations do not un-deprecate the entity. \end{note} Redeclarations using different forms of the attribute (with or without the \grammarterm{attribute-argument-clause} or with different \grammarterm{attribute-argument-clause}{s}) are allowed. \pnum \recommended Implementations should use the \tcode{deprecated} attribute to produce a diagnostic message in case the program refers to a name or entity other than to declare it, after a declaration that specifies the attribute. The diagnostic message should include the text provided within the \grammarterm{attribute-argument-clause} of any \tcode{deprecated} attribute applied to the name or entity. \rSec2[dcl.attr.fallthrough]{Fallthrough attribute} \indextext{attribute!fallthrough} \pnum The \grammarterm{attribute-token} \tcode{fallthrough} may be applied to a null statement\iref{stmt.expr}; \indextext{statement!fallthrough} such a statement is a fallthrough statement. No \grammarterm{attribute-argument-clause} shall be present. A fallthrough statement may only appear within an enclosing \keyword{switch} statement\iref{stmt.switch}. The next statement that would be executed after a fallthrough statement shall be a labeled statement whose label is a case label or default label for the same \keyword{switch} statement and, if the fallthrough statement is contained in an iteration statement, the next statement shall be part of the same execution of the substatement of the innermost enclosing iteration statement. The program is ill-formed if there is no such statement. \pnum \recommended The use of a fallthrough statement should suppress a warning that an implementation might otherwise issue for a case or default label that is reachable from another case or default label along some path of execution. Implementations should issue a warning if a fallthrough statement is not dynamically reachable. \pnum \begin{example} \begin{codeblock} void f(int n) { void g(), h(), i(); switch (n) { case 1: case 2: g(); [[fallthrough]]; case 3: // warning on fallthrough discouraged do { [[fallthrough]]; // error: next statement is not part of the same substatement execution } while (false); case 6: do { [[fallthrough]]; // error: next statement is not part of the same substatement execution } while (n--); case 7: while (false) { [[fallthrough]]; // error: next statement is not part of the same substatement execution } case 5: h(); case 4: // implementation may warn on fallthrough i(); [[fallthrough]]; // error } } \end{codeblock} \end{example} \rSec2[dcl.attr.likelihood]{Likelihood attributes}% \indextext{attribute!likely} \indextext{attribute!unlikely} \pnum The \grammarterm{attribute-token}s \tcode{likely} and \tcode{unlikely} may be applied to labels or statements. No \grammarterm{attribute-argument-clause} shall be present. The \grammarterm{attribute-token} \tcode{likely} shall not appear in an \grammarterm{attribute-specifier-seq} that contains the \grammarterm{attribute-token} \tcode{unlikely}. \pnum \recommended The use of the \tcode{likely} attribute is intended to allow implementations to optimize for the case where paths of execution including it are arbitrarily more likely than any alternative path of execution that does not include such an attribute on a statement or label. The use of the \tcode{unlikely} attribute is intended to allow implementations to optimize for the case where paths of execution including it are arbitrarily more unlikely than any alternative path of execution that does not include such an attribute on a statement or label. A path of execution includes a label if and only if it contains a jump to that label. \begin{note} Excessive usage of either of these attributes is liable to result in performance degradation. \end{note} \pnum \begin{example} \begin{codeblock} void g(int); int f(int n) { if (n > 5) [[unlikely]] { // \tcode{n > 5} is considered to be arbitrarily unlikely g(0); return n * 2 + 1; } switch (n) { case 1: g(1); [[fallthrough]]; [[likely]] case 2: // \tcode{n == 2} is considered to be arbitrarily more g(2); // likely than any other value of \tcode{n} break; } return 3; } \end{codeblock} \end{example} \rSec2[dcl.attr.unused]{Maybe unused attribute}% \indextext{attribute!maybe unused} \pnum The \grammarterm{attribute-token} \tcode{maybe_unused} indicates that a name or entity is possibly intentionally unused. No \grammarterm{attribute-argument-clause} shall be present. \pnum The attribute may be applied to the declaration of a class, a \grammarterm{typedef-name}, a variable (including a structured binding declaration), a non-static data member, a function, an enumeration, or an enumerator. \pnum A name or entity declared without the \tcode{maybe_unused} attribute can later be redeclared with the attribute and vice versa. An entity is considered marked after the first declaration that marks it. \pnum \recommended For an entity marked \tcode{maybe_unused}, implementations should not emit a warning that the entity or its structured bindings (if any) are used or unused. For a structured binding declaration not marked \tcode{maybe_unused}, implementations should not emit such a warning unless all of its structured bindings are unused. \pnum \begin{example} \begin{codeblock} [[maybe_unused]] void f([[maybe_unused]] bool thing1, [[maybe_unused]] bool thing2) { [[maybe_unused]] bool b = thing1 && thing2; assert(b); } \end{codeblock} Implementations should not warn that \tcode{b} is unused, whether or not \tcode{NDEBUG} is defined. \end{example} \rSec2[dcl.attr.nodiscard]{Nodiscard attribute}% \indextext{attribute!nodiscard} \pnum The \grammarterm{attribute-token} \tcode{nodiscard} may be applied to a function or a lambda call operator or to the declaration of a class or enumeration. An \grammarterm{attribute-argument-clause} may be present and, if present, shall have the form: \begin{ncbnf} \terminal{(} string-literal \terminal{)} \end{ncbnf} \pnum A name or entity declared without the \tcode{nodiscard} attribute can later be redeclared with the attribute and vice-versa. \begin{note} Thus, an entity initially declared without the attribute can be marked as \tcode{nodiscard} by a subsequent redeclaration. However, after an entity is marked as \tcode{nodiscard}, later redeclarations do not remove the \tcode{nodiscard} from the entity. \end{note} Redeclarations using different forms of the attribute (with or without the \grammarterm{attribute-argument-clause} or with different \grammarterm{attribute-argument-clause}s) are allowed. \pnum A \defnadj{nodiscard}{type} is a (possibly cv-qualified) class or enumeration type marked \tcode{nodiscard} in a reachable declaration. A \defnadj{nodiscard}{call} is either \begin{itemize} \item a function call expression\iref{expr.call} that calls a function declared \tcode{nodiscard} in a reachable declaration or whose return type is a nodiscard type, or \item an explicit type conversion\iref{expr.type.conv,expr.static.cast,expr.cast} that constructs an object through a constructor declared \tcode{nodiscard} in a reachable declaration, or that initializes an object of a nodiscard type. \end{itemize} \pnum \recommended Appearance of a nodiscard call as a potentially-evaluated discarded-value expression\iref{expr.prop} is discouraged unless explicitly cast to \keyword{void}. Implementations should issue a warning in such cases. \begin{note} This is typically because discarding the return value of a nodiscard call has surprising consequences. \end{note} The \grammarterm{string-literal} in a \tcode{nodiscard} \grammarterm{attribute-argument-clause} should be used in the message of the warning as the rationale for why the result should not be discarded. \pnum \begin{example} \begin{codeblock} struct [[nodiscard]] my_scopeguard { @\commentellip@ }; struct my_unique { my_unique() = default; // does not acquire resource [[nodiscard]] my_unique(int fd) { @\commentellip@ } // acquires resource ~my_unique() noexcept { @\commentellip@ } // releases resource, if any @\commentellip@ }; struct [[nodiscard]] error_info { @\commentellip@ }; error_info enable_missile_safety_mode(); void launch_missiles(); void test_missiles() { my_scopeguard(); // warning encouraged (void)my_scopeguard(), // warning not encouraged, cast to \keyword{void} launch_missiles(); // comma operator, statement continues my_unique(42); // warning encouraged my_unique(); // warning not encouraged enable_missile_safety_mode(); // warning encouraged launch_missiles(); } error_info &foo(); void f() { foo(); } // warning not encouraged: not a nodiscard call, because neither // the (reference) return type nor the function is declared nodiscard \end{codeblock} \end{example} \rSec2[dcl.attr.noreturn]{Noreturn attribute}% \indextext{attribute!noreturn} \pnum The \grammarterm{attribute-token} \tcode{noreturn} specifies that a function does not return. No \grammarterm{attribute-argument-clause} shall be present. The attribute may be applied to a function or a lambda call operator. The first declaration of a function shall specify the \tcode{noreturn} attribute if any declaration of that function specifies the \tcode{noreturn} attribute. If a function is declared with the \tcode{noreturn} attribute in one translation unit and the same function is declared without the \tcode{noreturn} attribute in another translation unit, the program is ill-formed, no diagnostic required. \pnum If a function \tcode{f} is called where \tcode{f} was previously declared with the \tcode{noreturn} attribute and \tcode{f} eventually returns, the behavior is undefined. \begin{note} The function may terminate by throwing an exception. \end{note} \pnum \recommended Implementations should issue a warning if a function marked \tcode{[[noreturn]]} might return. \pnum \begin{example} \begin{codeblock} [[ noreturn ]] void f() { throw "error"; // OK } [[ noreturn ]] void q(int i) { // behavior is undefined if called with an argument \tcode{<= 0} if (i > 0) throw "positive"; } \end{codeblock} \end{example} \rSec2[dcl.attr.nouniqueaddr]{No unique address attribute}% \indextext{attribute!no unique address} \pnum The \grammarterm{attribute-token} \tcode{no_unique_address} specifies that a non-static data member is a potentially-overlapping subobject\iref{intro.object}. No \grammarterm{attribute-argument-clause} shall be present. The attribute may appertain to a non-static data member other than a bit-field. \pnum \begin{note} The non-static data member can share the address of another non-static data member or that of a base class, and any padding that would normally be inserted at the end of the object can be reused as storage for other members. \end{note} \begin{example} \begin{codeblock} template class hash_map { [[no_unique_address]] Hash hasher; [[no_unique_address]] Pred pred; [[no_unique_address]] Allocator alloc; Bucket *buckets; // ... public: // ... }; \end{codeblock} Here, \tcode{hasher}, \tcode{pred}, and \tcode{alloc} could have the same address as \tcode{buckets} if their respective types are all empty. \end{example}