[expr.prim] # 7 Expressions [[expr]](./#expr) ## 7.5 Primary expressions [expr.prim] ### [7.5.1](#grammar) Grammar [[expr.prim.grammar]](expr.prim.grammar) [primary-expression:](#nt:primary-expression "7.5.1 Grammar [expr.prim.grammar]") [*literal*](lex.literal.kinds#nt:literal "5.13.1 Kinds of literals [lex.literal.kinds]") this ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ) [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") [*fold-expression*](#nt:fold-expression "7.5.7 Fold expressions [expr.prim.fold]") [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") [*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") ### [7.5.2](#literal) Literals [[expr.prim.literal]](expr.prim.literal) [1](#literal-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1249) The type of a [*literal*](lex.literal.kinds#nt:literal "5.13.1 Kinds of literals [lex.literal.kinds]") is determined based on its form as specified in [[lex.literal]](lex.literal "5.13 Literals")[.](#literal-1.sentence-1) A [*string-literal*](lex.string#nt:string-literal "5.13.5 String literals [lex.string]") is an lvalue designating a corresponding string literal object ([[lex.string]](lex.string "5.13.5 String literals")), a [*user-defined-literal*](lex.ext#nt:user-defined-literal "5.13.9 User-defined literals [lex.ext]") has the same value category as the corresponding operator call expression described in [[lex.ext]](lex.ext "5.13.9 User-defined literals"), and any other [*literal*](lex.literal.kinds#nt:literal "5.13.1 Kinds of literals [lex.literal.kinds]") is a prvalue[.](#literal-1.sentence-2) ### [7.5.3](#this) This [[expr.prim.this]](expr.prim.this) [1](#this-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1263) The keyword this names a pointer to the object for which an implicit object member function ([[class.mfct.non.static]](class.mfct.non.static "11.4.3 Non-static member functions")) is invoked or a non-static data member's initializer ([[class.mem]](class.mem "11.4 Class members")) is evaluated[.](#this-1.sentence-1) [2](#this-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1269) The [*current class*](#def:class,current "7.5.3 This [expr.prim.this]") at a program point is the class associated with the innermost class scope containing that point[.](#this-2.sentence-1) [*Note [1](#this-note-1)*: A [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") does not introduce a class scope[.](#this-2.sentence-2) — *end note*] [3](#this-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1276) If the expression this appears within the predicate of a contract assertion ([[basic.contract.general]](basic.contract.general "6.11.1 General")) (including as the result of an implicit transformation ([[expr.prim.id.general]](#id.general "7.5.5.1 General")) and including in the bodies of nested [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")*s*) and the current class encloses the contract assertion,const is combined with the [*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") used to generate the resulting type (see below)[.](#this-3.sentence-1) [4](#this-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1286) If a declaration declares a member function or member function template of a class X, the expression this is a prvalue of type “pointer to[*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") X” wherever X is the current class between the optional[*cv-qualifier-seq*](dcl.decl.general#nt:cv-qualifier-seq "9.3.1 General [dcl.decl.general]") and the end of the [*function-definition*](dcl.fct.def.general#nt:function-definition "9.6.1 General [dcl.fct.def.general]"),[*member-declarator*](class.mem.general#nt:member-declarator "11.4.1 General [class.mem.general]"), or [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]")[.](#this-4.sentence-1) It shall not appear within the declaration of a static or explicit object member function of the current class (although its type and value category are defined within such member functions as they are within an implicit object member function)[.](#this-4.sentence-2) [*Note [2](#this-note-2)*: This is because declaration matching does not occur until the complete declarator is known[.](#this-4.sentence-3) — *end note*] [*Note [3](#this-note-3)*: In a [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]"), the class being defined is not required to be complete for purposes of [class member access](expr.ref "7.6.1.5 Class member access [expr.ref]")[.](#this-4.sentence-4) Class members declared later are not visible[.](#this-4.sentence-5) [*Example [1](#this-example-1)*: struct A {char g(); template auto f(T t) -> decltype(t + g()){ return t + g(); }};template auto A::f(int t) -> decltype(t + g()); — *end example*] — *end note*] [5](#this-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1320) Otherwise, if a [*member-declarator*](class.mem.general#nt:member-declarator "11.4.1 General [class.mem.general]") declares a non-static data member ([[class.mem]](class.mem "11.4 Class members")) of a class X, the expression this is a prvalue of type “pointer to X” wherever X is the current class within the optional default member initializer ([[class.mem]](class.mem "11.4 Class members"))[.](#this-5.sentence-1) [6](#this-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1328) The expression this shall not appear in any other context[.](#this-6.sentence-1) [*Example [2](#this-example-2)*: class Outer {int a[sizeof(*this)]; // error: not inside a member functionunsigned int sz = sizeof(*this); // OK, in default member initializervoid f() {int b[sizeof(*this)]; // OKstruct Inner {int c[sizeof(*this)]; // error: not inside a member function of Inner}; }}; — *end example*] ### [7.5.4](#paren) Parentheses [[expr.prim.paren]](expr.prim.paren) [1](#paren-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1349) A parenthesized expression (E) is a primary expression whose type, result, and value category are identical to those of E[.](#paren-1.sentence-1) The parenthesized expression can be used in exactly the same contexts as those where E can be used, and with the same meaning, except as otherwise indicated[.](#paren-1.sentence-2) ### [7.5.5](#id) Names [[expr.prim.id]](expr.prim.id) #### [7.5.5.1](#id.general) General [[expr.prim.id.general]](expr.prim.id.general) [id-expression:](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") [*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") [*pack-index-expression*](#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]") [1](#id.general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1368) An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is a restricted form of a[*primary-expression*](#nt:primary-expression "7.5.1 Grammar [expr.prim.grammar]")[.](#id.general-1.sentence-1) [*Note [1](#id.general-note-1)*: An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") can appear after[. and -> operators](expr.ref "7.6.1.5 Class member access [expr.ref]")[.](#id.general-1.sentence-2) — *end note*] [2](#id.general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1378) If an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") E denotes a non-static non-type member of some class C at a point where the current class ([[expr.prim.this]](#this "7.5.3 This")) is X and - [(2.1)](#id.general-2.1) E is potentially evaluated orC is X or a base class of X, and - [(2.2)](#id.general-2.2) E is not the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") of a class member access expression ([[expr.ref]](expr.ref "7.6.1.5 Class member access")), and - [(2.3)](#id.general-2.3) E is not the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") of a [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") ([[expr.reflect]](expr.reflect "7.6.2.10 The reflection operator")), and - [(2.4)](#id.general-2.4) if E is a [*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]"),E is not the un-parenthesized operand of the unary & operator ([[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators")), the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is transformed into a class member access expression using (*this) as the object expression[.](#id.general-2.sentence-1) If this transformation occurs in the predicate of a precondition assertion of a constructor of X or a postcondition assertion of a destructor of X, the expression is ill-formed[.](#id.general-2.sentence-2) [*Note [2](#id.general-note-2)*: If C is not X or a base class of X, the class member access expression is ill-formed[.](#id.general-2.sentence-3) Also, if the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") occurs within a static or explicit object member function, the class member access is ill-formed[.](#id.general-2.sentence-4) — *end note*] This transformation does not apply in the template definition context ([[temp.dep.type]](temp.dep.type "13.8.3.2 Dependent types"))[.](#id.general-2.sentence-5) [*Example [1](#id.general-example-1)*: struct C {bool b; C() pre(b) // error pre(&this->b) // OK pre(sizeof(b) > 0); // OK, b is not potentially evaluated.}; — *end example*] [3](#id.general-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1423) If an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") E denotes a member M of an anonymous union ([[class.union.anon]](class.union.anon "11.5.2 Anonymous unions")) U: - [(3.1)](#id.general-3.1) If U is a non-static data member,E refers to M as a member of the lookup context of the terminal name of E (after any implicit transformation to a class member access expression)[.](#id.general-3.1.sentence-1) [*Example [2](#id.general-example-2)*: o.x is interpreted as o.u.x, where u names the anonymous union member[.](#id.general-3.1.sentence-2) — *end example*] - [(3.2)](#id.general-3.2) Otherwise, E is interpreted as a class member access ([[expr.ref]](expr.ref "7.6.1.5 Class member access")) that designates the member subobject M of the anonymous union variable for U[.](#id.general-3.2.sentence-1) [*Note [3](#id.general-note-3)*: Under this interpretation, E no longer denotes a non-static data member[.](#id.general-3.2.sentence-2) — *end note*] [*Example [3](#id.general-example-3)*: N​::​x is interpreted as N​::​u.x, where u names the anonymous union variable[.](#id.general-3.2.sentence-3) — *end example*] [4](#id.general-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1449) An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") or [*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") that designates a non-static data member or implicit object member function of a class can only be used: - [(4.1)](#id.general-4.1) as part of a class member access (after any implicit transformation (see above)) in which the object expression refers to the member's class or a class derived from that class, or - [(4.2)](#id.general-4.2) to form a pointer to member ([[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators")), or - [(4.3)](#id.general-4.3) if that [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") or [*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") designates a non-static data member and it appears in an unevaluated operand[.](#id.general-4.sentence-1) [*Example [4](#id.general-example-4)*: struct S {int m;};int i = sizeof(S::m); // OKint j = sizeof(S::m + 42); // OKint S::*k = &[:^^S::m:]; // OK — *end example*] [5](#id.general-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1479) For an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") that denotes an overload set, overload resolution is performed to select a unique function ([[over.match]](over.match "12.2 Overload resolution"), [[over.over]](over.over "12.3 Address of an overload set"))[.](#id.general-5.sentence-1) [*Note [4](#id.general-note-4)*: A program cannot refer to a function with a trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") whose [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") is not satisfied, because such functions are never selected by overload resolution[.](#id.general-5.sentence-2) [*Example [5](#id.general-example-5)*: template struct A {static void f(int) requires false;}; void g() { A::f(0); // error: cannot call fvoid (*p1)(int) = A::f; // error: cannot take the address of fdecltype(A::f)* p2 = nullptr; // error: the type decltype(A​::​f) is invalid} In each case, the constraints of f are not satisfied[.](#id.general-5.sentence-3) In the declaration of p2, those constraints need to be satisfied even thoughf is an [unevaluated operand](expr.context#def:unevaluated_operand "7.2.3 Context dependence [expr.context]")[.](#id.general-5.sentence-4) — *end example*] — *end note*] #### [7.5.5.2](#id.unqual) Unqualified names [[expr.prim.id.unqual]](expr.prim.id.unqual) [unqualified-id:](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*operator-function-id*](over.oper.general#nt:operator-function-id "12.4.1 General [over.oper.general]") [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]") [*literal-operator-id*](over.literal#nt:literal-operator-id "12.6 User-defined literals [over.literal]") ~ [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") ~ [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") [1](#id.unqual-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1521) An [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") is only an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") if it has been suitably declared ([[dcl]](dcl "9 Declarations")) or if it appears as part of a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") ([[dcl.decl]](dcl.decl "9.3 Declarators"))[.](#id.unqual-1.sentence-1) [*Note [1](#id.unqual-note-1)*: For [*operator-function-id*](over.oper.general#nt:operator-function-id "12.4.1 General [over.oper.general]")*s*, see [[over.oper]](over.oper "12.4 Overloaded operators"); for[*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]")*s*, see [[class.conv.fct]](class.conv.fct "11.4.8.3 Conversion functions"); for[*literal-operator-id*](over.literal#nt:literal-operator-id "12.6 User-defined literals [over.literal]")*s*, see [[over.literal]](over.literal "12.6 User-defined literals"); for[*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]")*s*, see [[temp.names]](temp.names "13.3 Names of template specializations")[.](#id.unqual-1.sentence-2) A [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") or [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") prefixed by ~ denotes the destructor of the type so named; see [[expr.prim.id.dtor]](#id.dtor "7.5.5.5 Destruction")[.](#id.unqual-1.sentence-3) — *end note*] [2](#id.unqual-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1537) A [*component name*](#def:component_name "7.5.5.2 Unqualified names [expr.prim.id.unqual]") of an [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") U is - [(2.1)](#id.unqual-2.1) U if it is a name or - [(2.2)](#id.unqual-2.2) the component name of the [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") or [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") of U, if any[.](#id.unqual-2.sentence-1) [*Note [2](#id.unqual-note-2)*: Other constructs that contain names to look up can have several component names ([[expr.prim.id.qual]](#id.qual "7.5.5.3 Qualified names"), [[dcl.type.simple]](dcl.type.simple "9.2.9.3 Simple type specifiers"), [[dcl.type.elab]](dcl.type.elab "9.2.9.5 Elaborated type specifiers"), [[dcl.mptr]](dcl.mptr "9.3.4.4 Pointers to members"), [[namespace.udecl]](namespace.udecl "9.10 The using declaration"), [[temp.param]](temp.param "13.2 Template parameters"), [[temp.names]](temp.names "13.3 Names of template specializations"), [[temp.res]](temp.res "13.8 Name resolution"))[.](#id.unqual-2.sentence-2) — *end note*] The [*terminal name*](#def:name,terminal "7.5.5.2 Unqualified names [expr.prim.id.unqual]") of a construct is the component name of that construct that appears lexically last[.](#id.unqual-2.sentence-3) [3](#id.unqual-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1554) The result is the entity denoted by the [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") ([[basic.lookup.unqual]](basic.lookup.unqual "6.5.3 Unqualified name lookup"))[.](#id.unqual-3.sentence-1) [4](#id.unqual-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1558) If - [(4.1)](#id.unqual-4.1) the [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") appears in a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") at program point P, - [(4.2)](#id.unqual-4.2) the entity is a local entity ([[basic.pre]](basic.pre "6.1 Preamble")) or a variable declared by an [*init-capture*](#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") ([[expr.prim.lambda.capture]](#lambda.capture "7.5.6.3 Captures")), - [(4.3)](#id.unqual-4.3) naming the entity within the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of the innermost enclosing [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") of P, but not in an unevaluated operand, would refer to an entity captured by copy in some intervening [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]"), and - [(4.4)](#id.unqual-4.4) P is in the function parameter scope, but not the [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]"), of the innermost such [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") E, then the type of the expression is the type of a class member access expression ([[expr.ref]](expr.ref "7.6.1.5 Class member access")) naming the non-static data member that would be declared for such a capture in the object parameter ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) of the function call operator of E[.](#id.unqual-4.sentence-1) [*Note [3](#id.unqual-note-3)*: If E is not declared mutable, the type of such an identifier will typically be const qualified[.](#id.unqual-4.sentence-2) — *end note*] [5](#id.unqual-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1589) Otherwise, if the [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") names a coroutine parameter, the type of the expression is that of the copy of the parameter ([[dcl.fct.def.coroutine]](dcl.fct.def.coroutine "9.6.4 Coroutine definitions")), and the result is that copy[.](#id.unqual-5.sentence-1) [6](#id.unqual-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1597) Otherwise, if the [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") names a result binding ([[dcl.contract.res]](dcl.contract.res "9.4.2 Referring to the result object")) attached to a function *f* with return type U, - [(6.1)](#id.unqual-6.1) if U is “reference to T”, then the type of the expression isconst T; - [(6.2)](#id.unqual-6.2) otherwise, the type of the expression is const U[.](#id.unqual-6.sentence-1) [7](#id.unqual-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1613) Otherwise, if the [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") appears in the predicate of a contract assertion C ([[basic.contract]](basic.contract "6.11 Contract assertions")) and the entity is - [(7.1)](#id.unqual-7.1) a variable declared outside of C of object type T, - [(7.2)](#id.unqual-7.2) a variable or template parameter declared outside of C of type “reference to T”, or - [(7.3)](#id.unqual-7.3) a structured binding of type T whose corresponding variable is declared outside of C, then the type of the expression is const T[.](#id.unqual-7.sentence-1) [8](#id.unqual-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1635) [*Example [1](#id.unqual-example-1)*: int n = 0;struct X { bool m(); }; struct Y {int z = 0; void f(int i, int* p, int& r, X x, X* px) pre (++n) // error: attempting to modify const lvalue pre (++i) // error: attempting to modify const lvalue pre (++(*p)) // OK pre (++r) // error: attempting to modify const lvalue pre (x.m()) // error: calling non-const member function pre (px->m()) // OK pre ([=,&i,*this] mutable {++n; // error: attempting to modify const lvalue++i; // error: attempting to modify const lvalue++p; // OK, refers to member of closure type++r; // OK, refers to non-reference member of closure type++this->z; // OK, captured *this++z; // OK, captured *thisint j = 17; [&]{int k = 34; ++i; // error: attempting to modify const lvalue++j; // OK++k; // OK}(); return true; }()); template void g() pre(++N) // error: attempting to modify prvalue pre(++R) // error: attempting to modify const lvalue pre(++(*P)); // OKint h() post(r : ++r) // error: attempting to modify const lvalue post(r: [=] mutable {++r; // OK, refers to member of closure typereturn true; }()); int& k() post(r : ++r); // error: attempting to modify const lvalue}; — *end example*] [9](#id.unqual-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1687) Otherwise, if the entity is a template parameter object for a template parameter of type T ([[temp.param]](temp.param "13.2 Template parameters")), the type of the expression is const T[.](#id.unqual-9.sentence-1) [10](#id.unqual-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1692) In all other cases, the type of the expression is the type of the entity[.](#id.unqual-10.sentence-1) [11](#id.unqual-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1695) [*Note [4](#id.unqual-note-4)*: The type will be adjusted as described in [[expr.type]](expr.type "7.2.2 Type") if it is cv-qualified or is a reference type[.](#id.unqual-11.sentence-1) — *end note*] [12](#id.unqual-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1701) The expression is an xvalue if it is move-eligible (see below); an lvalue if the entity is a function, variable, structured binding ([[dcl.struct.bind]](dcl.struct.bind "9.7 Structured binding declarations")), result binding ([[dcl.contract.res]](dcl.contract.res "9.4.2 Referring to the result object")), data member, or template parameter object; and a prvalue otherwise ([[basic.lval]](basic.lval "7.2.1 Value category")); it is a bit-field if the identifier designates a bit-field[.](#id.unqual-12.sentence-1) [13](#id.unqual-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1714) If an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") E appears in the predicate of a function contract assertion attached to a function *f* and denotes a function parameter of *f* and the implementation introduces any temporary objects to hold the value of that parameter as specified in [[class.temporary]](class.temporary "6.8.7 Temporary objects"), - [(13.1)](#id.unqual-13.1) if the contract assertion is a precondition assertion and the evaluation of the precondition assertion is sequenced before the initialization of the parameter object,E refers to the most recently initialized such temporary object, and - [(13.2)](#id.unqual-13.2) if the contract assertion is a postcondition assertion, it is unspecified whether E refers to one of the temporary objects or the parameter object; the choice is consistent within a single evaluation of a postcondition assertion[.](#id.unqual-13.sentence-1) [14](#id.unqual-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1737) If an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") E names a result binding in a postcondition assertion and the implementation introduces any temporary objects to hold the result object as specified in [[class.temporary]](class.temporary "6.8.7 Temporary objects"), and the postcondition assertion is sequenced before the initialization of the result object ([[expr.call]](expr.call "7.6.1.3 Function call")),E refers to the most recently initialized such temporary object[.](#id.unqual-14.sentence-1) [*Example [2](#id.unqual-example-2)*: void f() {float x, &r = x; [=]() -> decltype((x)) { // lambda returns float const& because this lambda is not mutable and// x is an lvaluedecltype(x) y1; // y1 has type floatdecltype((x)) y2 = y1; // y2 has type float const&decltype(r) r1 = y1; // r1 has type float&decltype((r)) r2 = y2; // r2 has type float const&return y2; }; [=](decltype((x)) y) {decltype((x)) z = x; // OK, y has type float&, z has type float const&}; [=] {[](decltype((x)) y) {}; // OK, lambda takes a parameter of type float const&[x=1](decltype((x)) y) {decltype((x)) z = x; // OK, y has type int&, z has type int const&}; };} — *end example*] [15](#id.unqual-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1777) An [*implicitly movable entity*](#def:entity,implicitly_movable "7.5.5.2 Unqualified names [expr.prim.id.unqual]") is a variable with automatic storage duration that is either a non-volatile object or an rvalue reference to a non-volatile object type[.](#id.unqual-15.sentence-1) An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") or[*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") ([[expr.prim.splice]](#splice "7.5.9 Expression splicing")) is [*move-eligible*](#def:move-eligible "7.5.5.2 Unqualified names [expr.prim.id.unqual]") if - [(15.1)](#id.unqual-15.1) it designates an implicitly movable entity, - [(15.2)](#id.unqual-15.2) it is the (possibly parenthesized) operand of a return ([[stmt.return]](stmt.return "8.8.4 The return statement")) orco_return ([[stmt.return.coroutine]](stmt.return.coroutine "8.8.5 The co_­return statement")) statement or of a [*throw-expression*](expr.throw#nt:throw-expression "7.6.18 Throwing an exception [expr.throw]") ([[expr.throw]](expr.throw "7.6.18 Throwing an exception")), and - [(15.3)](#id.unqual-15.3) each intervening scope between the declaration of the entity and the innermost enclosing scope of the expression is a block scope and, for a [*throw-expression*](expr.throw#nt:throw-expression "7.6.18 Throwing an exception [expr.throw]"), is not the block scope of a [*try-block*](except.pre#nt:try-block "14.1 Preamble [except.pre]") or [*function-try-block*](except.pre#nt:function-try-block "14.1 Preamble [except.pre]")[.](#id.unqual-15.sentence-2) #### [7.5.5.3](#id.qual) Qualified names [[expr.prim.id.qual]](expr.prim.id.qual) [qualified-id:](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") templateopt [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") [nested-name-specifier:](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") :: [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") :: [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]") :: [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") :: [*splice-scope-specifier*](#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") :: [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") :: [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") templateopt [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") :: [splice-scope-specifier:](#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") templateopt [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") [1](#id.qual-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1832) The component names of a [*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") are those of its [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") and [*unqualified-id*](#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]")[.](#id.qual-1.sentence-1) The component names of a [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") are its [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") (if any) and those of its[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]"),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]"),[*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]"), and/or[*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#id.qual-1.sentence-2) [2](#id.qual-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1843) A [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") that is not followed by ​::​ is never interpreted as part of a [*splice-scope-specifier*](#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#id.qual-2.sentence-1) The keyword template may only be omitted from the formtemplateopt [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") ​::​ when the [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") is preceded by typename[.](#id.qual-2.sentence-2) [*Example [1](#id.qual-example-1)*: templatestruct TCls {static constexpr int s = V; using type = int;}; int v1 = [:^^TCls<1>:]::s;int v2 = template [:^^TCls:]<2>::s; // OK, template binds to [*splice-scope-specifier*](#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")typename [:^^TCls:]<3>::type v3 = 3; // OK, typename binds to the qualified nametemplate [:^^TCls:]<3>::type v4 = 4; // OK, template binds to the [*splice-scope-specifier*](#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")typename template [:^^TCls:]<3>::type v5 = 5; // OK, same as v3[:^^TCls:]<3>::type v6 = 6; // error: unexpected < — *end example*] [3](#id.qual-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1870) A [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") is [*declarative*](#def:declarative "7.5.5.3 Qualified names [expr.prim.id.qual]") if it is part of - [(3.1)](#id.qual-3.1) a [*class-head-name*](class.pre#nt:class-head-name "11.1 Preamble [class.pre]"), - [(3.2)](#id.qual-3.2) an [*enum-head-name*](dcl.enum#nt:enum-head-name "9.8.1 Enumeration declarations [dcl.enum]"), - [(3.3)](#id.qual-3.3) a [*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") that is the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") of a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]"), or - [(3.4)](#id.qual-3.4) a declarative [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#id.qual-3.sentence-1) A declarative [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") shall not have a [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") or a [*splice-scope-specifier*](#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")[.](#id.qual-3.sentence-2) A declaration that uses a declarative [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") shall be a friend declaration or inhabit a scope that contains the entity being redeclared or specialized[.](#id.qual-3.sentence-3) [4](#id.qual-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1890) The entity designated by a [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") is determined as follows: - [(4.1)](#id.qual-4.1) The [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") ​::​ designates the global namespace[.](#id.qual-4.1.sentence-1) - [(4.2)](#id.qual-4.2) A [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") with a [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") designates the same type designated by the [*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]"), which shall be a class or enumeration type[.](#id.qual-4.2.sentence-1) - [(4.3)](#id.qual-4.3) For a [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") of the form [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") ​::​, the [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") shall designate a class or enumeration type or a namespace[.](#id.qual-4.3.sentence-1) The [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") designates the same entity as the [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]")[.](#id.qual-4.3.sentence-2) - [(4.4)](#id.qual-4.4) For a [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") of the formtemplateopt [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") ​::​, the [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") of the [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") shall designate a class template or an alias template T[.](#id.qual-4.4.sentence-1) Letting S be the specialization of T corresponding to the template argument list of the [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]"),S shall either be a class template specialization or an alias template specialization that denotes a class or enumeration type[.](#id.qual-4.4.sentence-2) The [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") designates the underlying entity of S[.](#id.qual-4.4.sentence-3) - [(4.5)](#id.qual-4.5) If a [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") N is declarative and has a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") with a template argument list A that involves a template parameter, let T be the template nominated by N without A[.](#id.qual-4.5.sentence-1) T shall be a class template[.](#id.qual-4.5.sentence-2) * [(4.5.1)](#id.qual-4.5.1) If A is the template argument list ([[temp.arg]](temp.arg "13.4 Template arguments")) of the corresponding [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") H ([[temp.mem]](temp.mem "13.7.3 Member templates")),N designates the primary template of T;H shall be equivalent to the [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") of T ([[temp.over.link]](temp.over.link "13.7.7.2 Function template overloading"))[.](#id.qual-4.5.1.sentence-1) * [(4.5.2)](#id.qual-4.5.2) Otherwise, N designates the partial specialization ([[temp.spec.partial]](temp.spec.partial "13.7.6 Partial specialization")) of T whose template argument list is equivalent to A ([[temp.over.link]](temp.over.link "13.7.7.2 Function template overloading")); the program is ill-formed if no such partial specialization exists[.](#id.qual-4.5.2.sentence-1) - [(4.6)](#id.qual-4.6) Any other [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") designates the entity denotes by its[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]"),[*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]"),[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]"), or[*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")[.](#id.qual-4.6.sentence-1) If the [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") is not declarative, the entity shall not be a template[.](#id.qual-4.6.sentence-2) [5](#id.qual-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1951) A [*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") shall not be of the form[*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") templateopt ~[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") nor of the form[*computed-type-specifier*](dcl.type.simple#nt:computed-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") ​::​ ~ [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]")[.](#id.qual-5.sentence-1) [6](#id.qual-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1958) The result of a [*qualified-id*](#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") Q is the entity it denotes ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup"))[.](#id.qual-6.sentence-1) [7](#id.qual-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1962) If Q appears in the predicate of a contract assertion C ([[basic.contract]](basic.contract "6.11 Contract assertions")) and the entity is - [(7.1)](#id.qual-7.1) a variable declared outside of C of object type T, - [(7.2)](#id.qual-7.2) a variable declared outside of C of type “reference to T”, or - [(7.3)](#id.qual-7.3) a structured binding of type T whose corresponding variable is declared outside of C, then the type of the expression is const T[.](#id.qual-7.sentence-1) [8](#id.qual-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1983) Otherwise, the type of the expression is the type of the result[.](#id.qual-8.sentence-1) [9](#id.qual-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L1986) The result is an lvalue if the member is - [(9.1)](#id.qual-9.1) a function other than a non-static member function, - [(9.2)](#id.qual-9.2) a non-static member function if Q is the operand of a unary & operator, - [(9.3)](#id.qual-9.3) a variable, - [(9.4)](#id.qual-9.4) a structured binding ([[dcl.struct.bind]](dcl.struct.bind "9.7 Structured binding declarations")), or - [(9.5)](#id.qual-9.5) a data member, and a prvalue otherwise[.](#id.qual-9.sentence-1) #### [7.5.5.4](#pack.index) Pack indexing expression [[expr.prim.pack.index]](expr.prim.pack.index) [pack-index-expression:](#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]") [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") ... [ [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") ] [1](#pack.index-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2010) The [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") P in a [*pack-index-expression*](#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]") shall be an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") that denotes a pack[.](#pack.index-1.sentence-1) [2](#pack.index-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2014) The [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") shall be a converted constant expression ([[expr.const]](expr.const "7.7 Constant expressions")) of type std​::​size_t whose value V, termed the index, is such that 0≤VC::~C2(); // OK, destroys *pc C().C::~C(); // undefined behavior: temporary of type C destroyed twiceusing T = int; 0 .T::~T(); // OK, no effect0.T::~T(); // error: 0.T is a [*user-defined-floating-point-literal*](lex.ext#nt:user-defined-floating-point-literal "5.13.9 User-defined literals [lex.ext]") ([[lex.ext]](lex.ext "5.13.9 User-defined literals"))} — *end example*] ### [7.5.6](#lambda) Lambda expressions [[expr.prim.lambda]](expr.prim.lambda) #### [7.5.6.1](#lambda.general) General [[expr.prim.lambda.general]](expr.prim.lambda.general) [lambda-expression:](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") [*lambda-introducer*](#nt:lambda-introducer "7.5.6.1 General [expr.prim.lambda.general]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*lambda-declarator*](#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") [*lambda-introducer*](#nt:lambda-introducer "7.5.6.1 General [expr.prim.lambda.general]") < [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") > [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]")opt [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*lambda-declarator*](#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") [lambda-introducer:](#nt:lambda-introducer "7.5.6.1 General [expr.prim.lambda.general]") [ [*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")opt ] [lambda-declarator:](#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") [*lambda-specifier-seq*](#nt:lambda-specifier-seq "7.5.6.1 General [expr.prim.lambda.general]") [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]")opt [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]")opt [*function-contract-specifier-seq*](dcl.contract.func#nt:function-contract-specifier-seq "9.4.1 General [dcl.contract.func]")opt [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]")opt [*function-contract-specifier-seq*](dcl.contract.func#nt:function-contract-specifier-seq "9.4.1 General [dcl.contract.func]")opt [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]")opt [*function-contract-specifier-seq*](dcl.contract.func#nt:function-contract-specifier-seq "9.4.1 General [dcl.contract.func]")opt ( [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") ) [*lambda-specifier-seq*](#nt:lambda-specifier-seq "7.5.6.1 General [expr.prim.lambda.general]")opt [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]")opt [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]")opt [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]")opt [*function-contract-specifier-seq*](dcl.contract.func#nt:function-contract-specifier-seq "9.4.1 General [dcl.contract.func]")opt [lambda-specifier:](#nt:lambda-specifier "7.5.6.1 General [expr.prim.lambda.general]") consteval constexpr mutable static [lambda-specifier-seq:](#nt:lambda-specifier-seq "7.5.6.1 General [expr.prim.lambda.general]") [*lambda-specifier*](#nt:lambda-specifier "7.5.6.1 General [expr.prim.lambda.general]") [*lambda-specifier-seq*](#nt:lambda-specifier-seq "7.5.6.1 General [expr.prim.lambda.general]")opt [1](#lambda.general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2106) A [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") provides a concise way to create a simple function object[.](#lambda.general-1.sentence-1) [*Example [1](#lambda.general-example-1)*: #include #include void abssort(float* x, unsigned N) { std::sort(x, x + N, [](float a, float b) { return std::abs(a) < std::abs(b); });} — *end example*] [2](#lambda.general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2119) A [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") is a prvalue whose result object is called the [*closure object*](#def:closure_object "7.5.6.1 General [expr.prim.lambda.general]")[.](#lambda.general-2.sentence-1) [*Note [1](#lambda.general-note-1)*: A closure object behaves like a [function object](function.objects "22.10 Function objects [function.objects]")[.](#lambda.general-2.sentence-2) — *end note*] [3](#lambda.general-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2127) An ambiguity can arise because a [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") can end in an [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]"), which collides with the [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") in [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")[.](#lambda.general-3.sentence-1) In such cases, any attributes are treated as[*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") in [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")[.](#lambda.general-3.sentence-2) [*Note [2](#lambda.general-note-2)*: Such ambiguous cases cannot have valid semantics because the constraint expression would not have type bool[.](#lambda.general-3.sentence-3) [*Example [2](#lambda.general-example-2)*: auto x = [] requires T::operator int [[some_attribute]] (int) { } — *end example*] — *end note*] [4](#lambda.general-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2146) A [*lambda-specifier-seq*](#nt:lambda-specifier-seq "7.5.6.1 General [expr.prim.lambda.general]") shall contain at most one of each [*lambda-specifier*](#nt:lambda-specifier "7.5.6.1 General [expr.prim.lambda.general]") and shall not contain both constexpr and consteval[.](#lambda.general-4.sentence-1) If the [*lambda-declarator*](#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") contains an explicit object parameter ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")), then no [*lambda-specifier*](#nt:lambda-specifier "7.5.6.1 General [expr.prim.lambda.general]") in the [*lambda-specifier-seq*](#nt:lambda-specifier-seq "7.5.6.1 General [expr.prim.lambda.general]") shall be mutable or static[.](#lambda.general-4.sentence-2) The [*lambda-specifier-seq*](#nt:lambda-specifier-seq "7.5.6.1 General [expr.prim.lambda.general]") shall not contain both mutable and static[.](#lambda.general-4.sentence-3) If the [*lambda-specifier-seq*](#nt:lambda-specifier-seq "7.5.6.1 General [expr.prim.lambda.general]") contains static, there shall be no [*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")[.](#lambda.general-4.sentence-4) [*Note [3](#lambda.general-note-3)*: The trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") is described in [[dcl.decl]](dcl.decl "9.3 Declarators")[.](#lambda.general-4.sentence-5) — *end note*] [5](#lambda.general-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2162) A [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")'s [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") is the [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") of the [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")'s [*lambda-declarator*](#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]"), if any, or empty otherwise[.](#lambda.general-5.sentence-1) If the [*lambda-declarator*](#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") does not include a [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]"), it is considered to be -> auto[.](#lambda.general-5.sentence-2) [*Note [4](#lambda.general-note-4)*: In that case, the return type is deduced from return statements as described in [[dcl.spec.auto]](dcl.spec.auto "9.2.9.7 Placeholder type specifiers")[.](#lambda.general-5.sentence-3) — *end note*] [*Example [3](#lambda.general-example-3)*: auto x1 = [](int i) { return i; }; // OK, return type is intauto x2 = []{ return { 1, 2 }; }; // error: deducing return type from [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]")int j;auto x3 = [&]()->auto&& { return j; }; // OK, return type is int& — *end example*] [6](#lambda.general-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2183) A lambda is a [*generic lambda*](#def:generic_lambda "7.5.6.1 General [expr.prim.lambda.general]") if the [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") has any generic parameter type placeholders ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7 Placeholder type specifiers")), or if the lambda has a [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]")[.](#lambda.general-6.sentence-1) [*Example [4](#lambda.general-example-4)*: auto x = [](int i, auto a) { return i; }; // OK, a generic lambdaauto y = [](this auto self, int i) { return i; }; // OK, a generic lambdaauto z = [](int i) { return i; }; // OK, a generic lambda — *end example*] #### [7.5.6.2](#lambda.closure) Closure types [[expr.prim.lambda.closure]](expr.prim.lambda.closure) [1](#lambda.closure-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2198) The type of a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") (which is also the type of the closure object) is a unique, unnamed non-union class type, called the [*closure type*](#def:closure_type "7.5.6.2 Closure types [expr.prim.lambda.closure]"), whose properties are described below[.](#lambda.closure-1.sentence-1) [2](#lambda.closure-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2204) The closure type is not complete until the end of its corresponding [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]")[.](#lambda.closure-2.sentence-1) [3](#lambda.closure-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2208) The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding[*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")[.](#lambda.closure-3.sentence-1) [*Note [1](#lambda.closure-note-1)*: This determines the set of namespaces and classes associated with the closure type ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4 Argument-dependent name lookup"))[.](#lambda.closure-3.sentence-2) The parameter types of a [*lambda-declarator*](#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") do not affect these associated namespaces and classes[.](#lambda.closure-3.sentence-3) — *end note*] [4](#lambda.closure-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2219) The closure type is not an aggregate type ([[dcl.init.aggr]](dcl.init.aggr "9.5.2 Aggregates")); it is a structural type ([[temp.param]](temp.param#term.structural.type "13.2 Template parameters")) if and only if the lambda has no [*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")[.](#lambda.closure-4.sentence-1) An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing: - [(4.1)](#lambda.closure-4.1) the size and/or alignment of the closure type, - [(4.2)](#lambda.closure-4.2) whether the closure type is trivially copyable ([[class.prop]](class.prop "11.2 Properties of classes")), - [(4.3)](#lambda.closure-4.3) whether the closure type is trivially relocatable ([[class.prop]](class.prop "11.2 Properties of classes")), - [(4.4)](#lambda.closure-4.4) whether the closure type is replaceable ([[class.prop]](class.prop "11.2 Properties of classes")), or - [(4.5)](#lambda.closure-4.5) whether the closure type is a standard-layout class ([[class.prop]](class.prop "11.2 Properties of classes"))[.](#lambda.closure-4.sentence-2) An implementation shall not add members of rvalue reference type to the closure type[.](#lambda.closure-4.sentence-3) [5](#lambda.closure-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2237) The closure type for a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") has a public inline function call operator (for a non-generic lambda) or function call operator template (for a generic lambda) ([[over.call]](over.call "12.4.4 Function call")) whose parameters and return type are those of the [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")'s[*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") and [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]") respectively, and whose[*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") consists of the specified [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]"), if any[.](#lambda.closure-5.sentence-1) The function call operator or the function call operator template are direct members of the closure type[.](#lambda.closure-5.sentence-2) The [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") of the function call operator template is the [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") immediately following< [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") >, if any[.](#lambda.closure-5.sentence-3) The trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") of the function call operator or operator template is the [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") of the [*lambda-declarator*](#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]"), if any[.](#lambda.closure-5.sentence-4) [*Note [2](#lambda.closure-note-2)*: The function call operator template for a generic lambda can be an abbreviated function template ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))[.](#lambda.closure-5.sentence-5) — *end note*] [*Example [1](#lambda.closure-example-1)*: auto glambda = [](auto a, auto&& b) { return a < b; };bool b = glambda(3, 3.14); // OKauto vglambda = [](auto printer) {return [=](auto&& ... ts) { // OK, ts is a function parameter pack printer(std::forward(ts)...); return [=]() { printer(ts ...); }; };};auto p = vglambda( [](auto v1, auto v2, auto v3){ std::cout << v1 << v2 << v3; } );auto q = p(1, 'a', 3.14); // OK, outputs 1a3.14 q(); // OK, outputs 1a3.14auto fact = [](this auto self, int n) -> int { // OK, explicit object parameterreturn (n <= 1) ? 1 : n * self(n-1);}; std::cout << fact(5); // OK, outputs 120 — *end example*] [6](#lambda.closure-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2285) Given a lambda with a [*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]"), the type of the explicit object parameter, if any, of the lambda's function call operator (possibly instantiated from a function call operator template) shall be either: - [(6.1)](#lambda.closure-6.1) the closure type, - [(6.2)](#lambda.closure-6.2) a class type publicly and unambiguously derived from the closure type, or - [(6.3)](#lambda.closure-6.3) a reference to a possibly cv-qualified such type[.](#lambda.closure-6.sentence-1) [*Example [2](#lambda.closure-example-2)*: struct C {template C(T);}; void func(int i) {int x = [=](this auto&&) { return i; }(); // OKint y = [=](this C) { return i; }(); // errorint z = [](this C) { return 42; }(); // OK} — *end example*] [7](#lambda.closure-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2314) The function call operator or operator template is a static member function or static member function template ([[class.static.mfct]](class.static.mfct "11.4.9.2 Static member functions")) if the [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")'s[*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") is followed by static[.](#lambda.closure-7.sentence-1) Otherwise, it is a non-static member function or member function template ([[class.mfct.non.static]](class.mfct.non.static "11.4.3 Non-static member functions")) that is declaredconst ([[class.mfct.non.static]](class.mfct.non.static "11.4.3 Non-static member functions")) if and only if the[*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")'s [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") is not followed by mutable and the [*lambda-declarator*](#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") does not contain an explicit object parameter[.](#lambda.closure-7.sentence-2) It is neither virtual nor declared volatile[.](#lambda.closure-7.sentence-3) Any [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]") or [*function-contract-specifier*](dcl.contract.func#nt:function-contract-specifier "9.4.1 General [dcl.contract.func]") ([[dcl.contract.func]](dcl.contract.func "9.4.1 General")) specified on a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") applies to the corresponding function call operator or operator template[.](#lambda.closure-7.sentence-4) An [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") in a [*lambda-declarator*](#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") appertains to the type of the corresponding function call operator or operator template[.](#lambda.closure-7.sentence-5) An [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") in a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") preceding a [*lambda-declarator*](#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") appertains to the corresponding function call operator or operator template[.](#lambda.closure-7.sentence-6) The function call operator or any given operator template specialization is a constexpr function if either the corresponding [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")'s[*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") is followed by constexpr or consteval, or it is constexpr-suitable ([[dcl.constexpr]](dcl.constexpr "9.2.6 The constexpr and consteval specifiers"))[.](#lambda.closure-7.sentence-7) It is an immediate function ([[dcl.constexpr]](dcl.constexpr "9.2.6 The constexpr and consteval specifiers")) if the corresponding [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")'s[*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") is followed by consteval[.](#lambda.closure-7.sentence-8) [*Example [3](#lambda.closure-example-3)*: auto ID = [](auto a) { return a; };static_assert(ID(3) == 3); // OKstruct NonLiteral { NonLiteral(int n) : n(n) { }int n;};static_assert(ID(NonLiteral{3}).n == 3); // error — *end example*] [8](#lambda.closure-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2358) [*Example [4](#lambda.closure-example-4)*: auto monoid = [](auto v) { return [=] { return v; }; };auto add = [](auto m1) constexpr {auto ret = m1(); return [=](auto m2) mutable {auto m1val = m1(); auto plus = [=](auto m2val) mutable constexpr{ return m1val += m2val; }; ret = plus(m2()); return monoid(ret); };};constexpr auto zero = monoid(0);constexpr auto one = monoid(1);static_assert(add(one)(zero)() == one()); // OK// Since two below is not declared constexpr, an evaluation of its constexpr member function call operator// cannot perform an lvalue-to-rvalue conversion on one of its subobjects (that represents its capture)// in a constant expression.auto two = monoid(2); assert(two() == 2); // OK, not a constant expression.static_assert(add(one)(one)() == two()); // error: two() is not a constant expressionstatic_assert(add(one)(one)() == monoid(2)()); // OK — *end example*] [9](#lambda.closure-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2386) [*Note [3](#lambda.closure-note-3)*: The function call operator or operator template can be constrained ([[temp.constr.decl]](temp.constr.decl "13.5.3 Constrained declarations")) by a [*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]") ([[temp.param]](temp.param "13.2 Template parameters")), a [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") ([[temp.pre]](temp.pre "13.1 Preamble")), or a trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") ([[dcl.decl]](dcl.decl "9.3 Declarators"))[.](#lambda.closure-9.sentence-1) [*Example [5](#lambda.closure-example-5)*: template concept C1 = /* ... */;template concept C2 = /* ... */;template concept C3 = /* ... */; auto f = [] requires C2(T1 a1, T1 b1, T2 a2, auto a3, auto a4) requires C3 {// T2 is constrained by a [*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]").// T1 and T2 are constrained by a [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]"), and// T2 and the type of a4 are constrained by a trailing [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]").}; — *end example*] — *end note*] [10](#lambda.closure-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2408) If all potential references to a local entity implicitly captured by a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") L occur within the function contract assertions ([[dcl.contract.func]](dcl.contract.func "9.4.1 General")) of the call operator or operator template of L or within [*assertion-statement*](stmt.contract.assert#nt:assertion-statement "8.9 Assertion statement [stmt.contract.assert]")*s* ([[stmt.contract.assert]](stmt.contract.assert "8.9 Assertion statement")) within the body of L, the program is ill-formed[.](#lambda.closure-10.sentence-1) [*Note [4](#lambda.closure-note-4)*: Adding a contract assertion to an existing C++ program cannot cause additional captures[.](#lambda.closure-10.sentence-2) — *end note*] [*Example [6](#lambda.closure-example-6)*: static int i = 0; void test() {auto f1 = [=] pre(i > 0) {}; // OK, no local entities are captured.int i = 1; auto f2 = [=] pre(i > 0) {}; // error: cannot implicitly capture i hereauto f3 = [i] pre(i > 0) {}; // OK, i is captured explicitly.auto f4 = [=] {contract_assert(i > 0); // error: cannot implicitly capture i here}; auto f5 = [=] {contract_assert(i > 0); // OK, i is referenced elsewhere.(void)i; }; auto f6 = [=] pre( // #1[]{bool x = true; return [=]{ return x; }(); // OK, #1 captures nothing.}()) {}; bool y = true; auto f7 = [=] pre([=]{ return y; }()); // error: outer capture of y is invalid.} — *end example*] [11](#lambda.closure-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2453) The closure type for a non-generic [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") with no[*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") and no explicit object parameter ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) whose constraints (if any) are satisfied has a conversion function to pointer to function with C++ language [linkage](dcl.link "9.12 Linkage specifications [dcl.link]") having the same parameter and return types as the closure type's function call operator[.](#lambda.closure-11.sentence-1) The conversion is to “pointer to noexcept function” if the function call operator has a non-throwing exception specification[.](#lambda.closure-11.sentence-2) If the function call operator is a static member function, then the value returned by this conversion function is a pointer to the function call operator[.](#lambda.closure-11.sentence-3) Otherwise, the value returned by this conversion function is a pointer to a function F that, when invoked, has the same effect as invoking the closure type's function call operator on a default-constructed instance of the closure type[.](#lambda.closure-11.sentence-4) F is a constexpr function if the function call operator is a constexpr function and is an immediate function if the function call operator is an immediate function[.](#lambda.closure-11.sentence-5) [12](#lambda.closure-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2476) For a generic lambda with no [*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") and no explicit object parameter ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")), the closure type has a conversion function template to pointer to function[.](#lambda.closure-12.sentence-1) The conversion function template has the same invented template parameter list, and the pointer to function has the same parameter types, as the function call operator template[.](#lambda.closure-12.sentence-2) The return type of the pointer to function shall behave as if it were a[*decltype-specifier*](dcl.type.decltype#nt:decltype-specifier "9.2.9.6 Decltype specifiers [dcl.type.decltype]") denoting the return type of the corresponding function call operator template specialization[.](#lambda.closure-12.sentence-3) [13](#lambda.closure-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2488) [*Note [5](#lambda.closure-note-5)*: If the generic lambda has no [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]") or the [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]") contains a placeholder type, return type deduction of the corresponding function call operator template specialization has to be done[.](#lambda.closure-13.sentence-1) The corresponding specialization is that instantiation of the function call operator template with the same template arguments as those deduced for the conversion function template[.](#lambda.closure-13.sentence-2) Consider the following:auto glambda = [](auto a) { return a; };int (*fp)(int) = glambda; The behavior of the conversion function of glambda above is like that of the following conversion function:struct Closure {template auto operator()(T t) const { /* ... */ }template static auto lambda_call_operator_invoker(T a) {// forwards execution to operator()(a) and therefore has// the same return type deduced/* ... */}template using fptr_t =decltype(lambda_call_operator_invoker(declval())) (*)(T); template operator fptr_t() const{ return &lambda_call_operator_invoker; }}; — *end note*] [*Example [7](#lambda.closure-example-7)*: void f1(int (*)(int)) { }void f2(char (*)(int)) { }void g(int (*)(int)) { } // #1void g(char (*)(char)) { } // #2void h(int (*)(int)) { } // #3void h(char (*)(int)) { } // #4auto glambda = [](auto a) { return a; }; f1(glambda); // OK f2(glambda); // error: ID is not convertible g(glambda); // error: ambiguous h(glambda); // OK, calls #3 since it is convertible from IDint& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK — *end example*] [14](#lambda.closure-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2539) If the function call operator template is a static member function template, then the value returned by any given specialization of this conversion function template is a pointer to the corresponding function call operator template specialization[.](#lambda.closure-14.sentence-1) Otherwise, the value returned by any given specialization of this conversion function template is a pointer to a function F that, when invoked, has the same effect as invoking the generic lambda's corresponding function call operator template specialization on a default-constructed instance of the closure type[.](#lambda.closure-14.sentence-2) F is a constexpr function if the corresponding specialization is a constexpr function andF is an immediate function if the function call operator template specialization is an immediate function[.](#lambda.closure-14.sentence-3) [*Note [6](#lambda.closure-note-6)*: This will result in the implicit instantiation of the generic lambda's body[.](#lambda.closure-14.sentence-4) The instantiated generic lambda's return type and parameter types need to match the return type and parameter types of the pointer to function[.](#lambda.closure-14.sentence-5) — *end note*] [*Example [8](#lambda.closure-example-8)*: auto GL = [](auto a) { std::cout << a; return a; };int (*GL_int)(int) = GL; // OK, through conversion function template GL_int(3); // OK, same as GL(3) — *end example*] [15](#lambda.closure-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2566) The conversion function or conversion function template is public, constexpr, non-virtual, non-explicit, const, and has a non-throwing [exception specification](except.spec "14.5 Exception specifications [except.spec]")[.](#lambda.closure-15.sentence-1) [*Example [9](#lambda.closure-example-9)*: auto Fwd = [](int (*fp)(int), auto a) { return fp(a); };auto C = [](auto a) { return a; }; static_assert(Fwd(C,3) == 3); // OK// No specialization of the function call operator template can be constexpr (due to the local static).auto NC = [](auto a) { static int s; return a; };static_assert(Fwd(NC,3) == 3); // error — *end example*] [16](#lambda.closure-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2583) The [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")'s [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") yields the [*function-body*](dcl.fct.def.general#nt:function-body "9.6.1 General [dcl.fct.def.general]") ([[dcl.fct.def]](dcl.fct.def "9.6 Function definitions")) of the function call operator, but it is not within the scope of the closure type[.](#lambda.closure-16.sentence-1) [*Example [10](#lambda.closure-example-10)*: struct S1 {int x, y; int operator()(int); void f() {[=]()->int {return operator()(this->x + y); // equivalent to S1​::​operator()(this->x + (*this).y)// this has type S1*}; }}; — *end example*] Unless the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") is that of a [*consteval-block-declaration*](dcl.pre#nt:consteval-block-declaration "9.1 Preamble [dcl.pre]") ([[dcl.pre]](dcl.pre "9.1 Preamble")), a variable __func__ is implicitly defined at the beginning of the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of the [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]"), with semantics as described in [[dcl.fct.def.general]](dcl.fct.def.general "9.6.1 General")[.](#lambda.closure-16.sentence-2) [17](#lambda.closure-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2607) The closure type associated with a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") has no default constructor if the [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") has a [*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") and a defaulted default constructor otherwise[.](#lambda.closure-17.sentence-1) It has a defaulted copy constructor and a defaulted move constructor ([[class.copy.ctor]](class.copy.ctor "11.4.5.3 Copy/move constructors"))[.](#lambda.closure-17.sentence-2) It has a deleted copy assignment operator if the [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") has a [*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") and defaulted copy and move assignment operators otherwise ([[class.copy.assign]](class.copy.assign "11.4.6 Copy/move assignment operator"))[.](#lambda.closure-17.sentence-3) [*Note [7](#lambda.closure-note-7)*: These special member functions are implicitly defined as usual, which can result in them being defined as deleted[.](#lambda.closure-17.sentence-4) — *end note*] [18](#lambda.closure-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2621) The closure type associated with a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") has an implicitly-declared destructor ([[class.dtor]](class.dtor "11.4.7 Destructors"))[.](#lambda.closure-18.sentence-1) [19](#lambda.closure-19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2625) A member of a closure type shall not be[explicitly instantiated](temp.explicit "13.9.3 Explicit instantiation [temp.explicit]"),[explicitly specialized](temp.expl.spec "13.9.4 Explicit specialization [temp.expl.spec]"), or named in a [friend declaration](class.friend "11.8.4 Friends [class.friend]")[.](#lambda.closure-19.sentence-1) #### [7.5.6.3](#lambda.capture) Captures [[expr.prim.lambda.capture]](expr.prim.lambda.capture) [lambda-capture:](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") [*capture-default*](#nt:capture-default "7.5.6.3 Captures [expr.prim.lambda.capture]") [*capture-list*](#nt:capture-list "7.5.6.3 Captures [expr.prim.lambda.capture]") [*capture-default*](#nt:capture-default "7.5.6.3 Captures [expr.prim.lambda.capture]") , [*capture-list*](#nt:capture-list "7.5.6.3 Captures [expr.prim.lambda.capture]") [capture-default:](#nt:capture-default "7.5.6.3 Captures [expr.prim.lambda.capture]") & = [capture-list:](#nt:capture-list "7.5.6.3 Captures [expr.prim.lambda.capture]") [*capture*](#nt:capture "7.5.6.3 Captures [expr.prim.lambda.capture]") [*capture-list*](#nt:capture-list "7.5.6.3 Captures [expr.prim.lambda.capture]") , [*capture*](#nt:capture "7.5.6.3 Captures [expr.prim.lambda.capture]") [capture:](#nt:capture "7.5.6.3 Captures [expr.prim.lambda.capture]") [*simple-capture*](#nt:simple-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") [*init-capture*](#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") [simple-capture:](#nt:simple-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") ...opt & [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") ...opt this * this [init-capture:](#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") ...opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]") & ...opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]") [1](#lambda.capture-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2672) The body of a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") may refer to local entities of enclosing scopes by capturing those entities, as described below[.](#lambda.capture-1.sentence-1) [2](#lambda.capture-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2677) If a [*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") includes a [*capture-default*](#nt:capture-default "7.5.6.3 Captures [expr.prim.lambda.capture]") that is &, no identifier in a [*simple-capture*](#nt:simple-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") of that[*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") shall be preceded by &[.](#lambda.capture-2.sentence-1) If a [*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") includes a[*capture-default*](#nt:capture-default "7.5.6.3 Captures [expr.prim.lambda.capture]") that is =, each[*simple-capture*](#nt:simple-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") of that [*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") shall be of the form “& [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") ...opt”, “this”, or “* this”[.](#lambda.capture-2.sentence-2) [*Note [1](#lambda.capture-note-1)*: The form [&,this] is redundant but accepted for compatibility with C++ 2014[.](#lambda.capture-2.sentence-3) — *end note*] Ignoring appearances in[*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]")*s* of [*init-capture*](#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")*s*, an identifier orthis shall not appear more than once in a[*lambda-capture*](#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")[.](#lambda.capture-2.sentence-4) [*Example [1](#lambda.capture-example-1)*: struct S2 { void f(int i); };void S2::f(int i) {[&, i]{ }; // OK[&, this, i]{ }; // OK, equivalent to [&, i][&, &i]{ }; // error: i preceded by & when & is the default[=, *this]{ }; // OK[=, this]{ }; // OK, equivalent to [=][i, i]{ }; // error: i repeated[this, *this]{ }; // error: this appears twice} — *end example*] [3](#lambda.capture-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2711) A [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") shall not have a [*capture-default*](#nt:capture-default "7.5.6.3 Captures [expr.prim.lambda.capture]") or [*simple-capture*](#nt:simple-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") in its [*lambda-introducer*](#nt:lambda-introducer "7.5.6.1 General [expr.prim.lambda.general]") unless - [(3.1)](#lambda.capture-3.1) its innermost enclosing scope is a block scope ([[basic.scope.block]](basic.scope.block "6.4.3 Block scope")), - [(3.2)](#lambda.capture-3.2) it appears within a default member initializer and its innermost enclosing scope is the corresponding class scope ([[basic.scope.class]](basic.scope.class "6.4.7 Class scope")), or - [(3.3)](#lambda.capture-3.3) it appears within a contract assertion and its innermost enclosing scope is the corresponding contract-assertion scope ([[basic.scope.contract]](basic.scope.contract "6.4.10 Contract-assertion scope"))[.](#lambda.capture-3.sentence-1) [4](#lambda.capture-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2729) The [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") in a [*simple-capture*](#nt:simple-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") shall denote a local entity ([[basic.lookup.unqual]](basic.lookup.unqual "6.5.3 Unqualified name lookup"), [[basic.pre]](basic.pre "6.1 Preamble"))[.](#lambda.capture-4.sentence-1) The [*simple-capture*](#nt:simple-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")*s* this and * this denote the local entity *this[.](#lambda.capture-4.sentence-2) An entity that is designated by a[*simple-capture*](#nt:simple-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") is said to be [*explicitly captured*](#def:explicitly_captured "7.5.6.3 Captures [expr.prim.lambda.capture]")[.](#lambda.capture-4.sentence-3) [5](#lambda.capture-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2738) If an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") in a [*capture*](#nt:capture "7.5.6.3 Captures [expr.prim.lambda.capture]") appears as the [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") of a parameter of the [*lambda-declarator*](#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]")'s [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") or as the name of a template parameter of the [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")'s [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]"), the program is ill-formed[.](#lambda.capture-5.sentence-1) [*Example [2](#lambda.capture-example-2)*: void f() {int x = 0; auto g = [x](int x) { return 0; }; // error: parameter and [*capture*](#nt:capture "7.5.6.3 Captures [expr.prim.lambda.capture]") have the same nameauto h = [y = 0](y) { return 0; }; // error: template parameter and [*capture*](#nt:capture "7.5.6.3 Captures [expr.prim.lambda.capture]")// have the same name} — *end example*] [6](#lambda.capture-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2756) An [*init-capture*](#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") inhabits the lambda scope ([[basic.scope.lambda]](basic.scope.lambda "6.4.5 Lambda scope")) of the [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")[.](#lambda.capture-6.sentence-1) An [*init-capture*](#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") without ellipsis behaves as if it declares and explicitly captures a variable of the form “auto [*init-capture*](#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") ;”, except that: - [(6.1)](#lambda.capture-6.1) if the capture is by copy (see below), the non-static data member declared for the capture and the variable are treated as two different ways of referring to the same object, which has the lifetime of the non-static data member, and no additional copy and destruction is performed, and - [(6.2)](#lambda.capture-6.2) if the capture is by reference, the variable's lifetime ends when the closure object's lifetime ends[.](#lambda.capture-6.sentence-2) [*Note [2](#lambda.capture-note-2)*: This enables an [*init-capture*](#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") like “x = std​::​move(x)”; the second “x” must bind to a declaration in the surrounding context[.](#lambda.capture-6.sentence-3) — *end note*] [*Example [3](#lambda.capture-example-3)*: int x = 4;auto y = [&r = x, x = x+1]()->int { r += 2; return x+2; }(); // Updates ​::​x to 6, and initializes y to 7.auto z = [a = 42](int a) { return 1; }; // error: parameter and conceptual local variable have the same nameauto counter = [i=0]() mutable -> decltype(i) { // OK, returns intreturn i++;}; — *end example*] [7](#lambda.capture-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2791) For the purposes of lambda capture, an expression potentially references local entities as follows: - [(7.1)](#lambda.capture-7.1) An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") that names a local entity potentially references that entity; an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") that names one or more non-static class members and does not form a pointer to member ([[expr.unary.op]](expr.unary.op "7.6.2.2 Unary operators")) potentially references *this[.](#lambda.capture-7.1.sentence-1) [*Note [3](#lambda.capture-note-3)*: This occurs even if overload resolution selects a static member function for the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]")[.](#lambda.capture-7.1.sentence-2) — *end note*] - [(7.2)](#lambda.capture-7.2) A this expression potentially references *this[.](#lambda.capture-7.2.sentence-1) - [(7.3)](#lambda.capture-7.3) A [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") potentially references the local entities named by its [*simple-capture*](#nt:simple-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")*s*[.](#lambda.capture-7.3.sentence-1) If an expression potentially references a local entity within a scope in which it is odr-usable ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule")), and the expression would be potentially evaluated if the effect of any enclosing typeid expressions ([[expr.typeid]](expr.typeid "7.6.1.8 Type identification")) were ignored, the entity is said to be [*implicitly captured*](#def:capture,implicit "7.5.6.3 Captures [expr.prim.lambda.capture]") by each intervening [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") with an associated[*capture-default*](#nt:capture-default "7.5.6.3 Captures [expr.prim.lambda.capture]") that does not explicitly capture it[.](#lambda.capture-7.sentence-2) The implicit capture of *this is deprecated when the[*capture-default*](#nt:capture-default "7.5.6.3 Captures [expr.prim.lambda.capture]") is =; see [[depr.capture.this]](depr.capture.this "D.3 Implicit capture of *this by reference")[.](#lambda.capture-7.sentence-3) [*Example [4](#lambda.capture-example-4)*: void f(int, const int (&)[2] = {}); // #1void f(const int&, const int (&)[1]); // #2void test() {const int x = 17; auto g = [](auto a) { f(x); // OK, calls #1, does not capture x}; auto g1 = [=](auto a) { f(x); // OK, calls #1, captures x}; auto g2 = [=](auto a) {int selector[sizeof(a) == 1 ? 1 : 2]{}; f(x, selector); // OK, captures x, can call #1 or #2}; auto g3 = [=](auto a) {typeid(a + x); // captures x regardless of whether a + x is an unevaluated operand};} Within g1, an implementation can optimize away the capture of x as it is not odr-used[.](#lambda.capture-7.sentence-4) — *end example*] [*Note [4](#lambda.capture-note-4)*: The set of captured entities is determined syntactically, and entities are implicitly captured even if the expression denoting a local entity is within a discarded statement ([[stmt.if]](stmt.if "8.5.2 The if statement"))[.](#lambda.capture-7.sentence-5) [*Example [5](#lambda.capture-example-5)*: templatevoid f(int n) {[=](auto a) {if constexpr (B && sizeof(a) > 4) {(void)n; // captures n regardless of the value of B and sizeof(int)}}(0);} — *end example*] — *end note*] [8](#lambda.capture-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2870) An entity is [*captured*](#def:captured "7.5.6.3 Captures [expr.prim.lambda.capture]") if it is captured explicitly or implicitly[.](#lambda.capture-8.sentence-1) An entity captured by a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") is odr-used ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule")) by the [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")[.](#lambda.capture-8.sentence-2) [*Note [5](#lambda.capture-note-5)*: As a consequence, if a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") explicitly captures an entity that is not odr-usable, the program is ill-formed ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule"))[.](#lambda.capture-8.sentence-3) — *end note*] [*Example [6](#lambda.capture-example-6)*: [🔗](#:Bond,James_Bond) void f1(int i) {int const N = 20; auto m1 = [=]{int const M = 30; auto m2 = [i]{int x[N][M]; // OK, N and M are not odr-used x[0][0] = i; // OK, i is explicitly captured by m2 and implicitly captured by m1}; }; struct s1 {int f; void work(int n) {int m = n*n; int j = 40; auto m3 = [this,m] {auto m4 = [&,j] { // error: j not odr-usable due to intervening lambda m3int x = n; // error: n is odr-used but not odr-usable due to intervening lambda m3 x += m; // OK, m implicitly captured by m4 and explicitly captured by m3 x += i; // error: i is odr-used but not odr-usable// due to intervening function and class scopes x += f; // OK, this captured implicitly by m4 and explicitly by m3}; }; }};}struct s2 {double ohseven = .007; auto f() {return [this] {return [*this] {return ohseven; // OK}; }(); }auto g() {return [] {return [*this] { }; // error: *this not captured by outer [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")}(); }}; — *end example*] [9](#lambda.capture-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2927) [*Note [6](#lambda.capture-note-6)*: Because local entities are not odr-usable within a default argument ([[basic.def.odr]](basic.def.odr "6.3 One-definition rule")), a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") appearing in a default argument cannot implicitly or explicitly capture any local entity[.](#lambda.capture-9.sentence-1) Such a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") can still have an [*init-capture*](#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") if any full-expression in its [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]") satisfies the constraints of an expression appearing in a default argument ([[dcl.fct.default]](dcl.fct.default "9.3.4.7 Default arguments"))[.](#lambda.capture-9.sentence-2) — *end note*] [*Example [7](#lambda.capture-example-7)*: void f2() {int i = 1; void g1(int = ([i]{ return i; })()); // errorvoid g2(int = ([i]{ return 0; })()); // errorvoid g3(int = ([=]{ return i; })()); // errorvoid g4(int = ([=]{ return 0; })()); // OKvoid g5(int = ([]{ return sizeof i; })()); // OKvoid g6(int = ([x=1]{ return x; })()); // OKvoid g7(int = ([x=i]{ return x; })()); // error} — *end example*] [10](#lambda.capture-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2954) An entity is [*captured by copy*](#def:captured,by_copy "7.5.6.3 Captures [expr.prim.lambda.capture]") if - [(10.1)](#lambda.capture-10.1) it is implicitly captured, the [*capture-default*](#nt:capture-default "7.5.6.3 Captures [expr.prim.lambda.capture]") is =, and the captured entity is not *this, or - [(10.2)](#lambda.capture-10.2) it is explicitly captured with a capture that is not of the formthis,& [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") ...opt, or& ...opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]")[.](#lambda.capture-10.sentence-1) For each entity captured by copy, an unnamed non-static data member is declared in the closure type[.](#lambda.capture-10.sentence-2) The declaration order of these members is unspecified[.](#lambda.capture-10.sentence-3) The type of such a data member is the referenced type if the entity is a reference to an object, an lvalue reference to the referenced function type if the entity is a reference to a function, or the type of the corresponding captured entity otherwise[.](#lambda.capture-10.sentence-4) A member of an anonymous union shall not be captured by copy[.](#lambda.capture-10.sentence-5) [11](#lambda.capture-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2975) Every [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") within the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of a[*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") that is an odr-use ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule")) of an entity captured by copy is transformed into an access to the corresponding unnamed data member of the closure type[.](#lambda.capture-11.sentence-1) [*Note [7](#lambda.capture-note-7)*: An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") that is not an odr-use refers to the original entity, never to a member of the closure type[.](#lambda.capture-11.sentence-2) However, such an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") can still cause the implicit capture of the entity[.](#lambda.capture-11.sentence-3) — *end note*] If *this is captured by copy, each expression that odr-uses *this is transformed to instead refer to the corresponding unnamed data member of the closure type[.](#lambda.capture-11.sentence-4) [*Example [8](#lambda.capture-example-8)*: void f(const int*);void g() {const int N = 10; [=] {int arr[N]; // OK, not an odr-use, refers to variable with automatic storage duration f(&N); // OK, causes N to be captured; &N points to// the corresponding member of the closure type};} — *end example*] [12](#lambda.capture-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3003) An entity is [*captured by reference*](#def:captured,by_reference "7.5.6.3 Captures [expr.prim.lambda.capture]") if it is implicitly or explicitly captured but not captured by copy[.](#lambda.capture-12.sentence-1) It is unspecified whether additional unnamed non-static data members are declared in the closure type for entities captured by reference[.](#lambda.capture-12.sentence-2) If declared, such non-static data members shall be of literal type[.](#lambda.capture-12.sentence-3) [*Example [9](#lambda.capture-example-9)*: // The inner closure type must be a literal type regardless of how reference captures are represented.static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4); — *end example*] A bit-field or a member of an anonymous union shall not be captured by reference[.](#lambda.capture-12.sentence-4) [13](#lambda.capture-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3018) An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") within the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") that is an odr-use of a reference captured by reference refers to the entity to which the captured reference is bound and not to the captured reference[.](#lambda.capture-13.sentence-1) [*Note [8](#lambda.capture-note-8)*: The validity of such captures is determined by the lifetime of the object to which the reference refers, not by the lifetime of the reference itself[.](#lambda.capture-13.sentence-2) — *end note*] [*Example [10](#lambda.capture-example-10)*: auto h(int &r) {return [&] {++r; // Valid after h returns if the lifetime of the// object to which r is bound has not ended};} — *end example*] [14](#lambda.capture-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3040) If a [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") m2 captures an entity and that entity is captured by an immediately enclosing [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")m1, thenm2's capture is transformed as follows: - [(14.1)](#lambda.capture-14.1) If m1 captures the entity by copy,m2 captures the corresponding non-static data member of m1's closure type; if m1 is not mutable, the non-static data member is considered to be const-qualified[.](#lambda.capture-14.1.sentence-1) - [(14.2)](#lambda.capture-14.2) If m1 captures the entity by reference,m2 captures the same entity captured by m1[.](#lambda.capture-14.2.sentence-1) [*Example [11](#lambda.capture-example-11)*: The nested [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")*s* and invocations below will output123234[.](#lambda.capture-14.sentence-2) int a = 1, b = 1, c = 1;auto m1 = [a, &b, &c]() mutable {auto m2 = [a, b, &c]() mutable { std::cout << a << b << c; a = 4; b = 4; c = 4; }; a = 3; b = 3; c = 3; m2();}; a = 2; b = 2; c = 2; m1(); std::cout << a << b << c; — *end example*] [15](#lambda.capture-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3073) When the [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") is evaluated, the entities that are captured by copy are used to direct-initialize each corresponding non-static data member of the resulting closure object, and the non-static data members corresponding to the[*init-capture*](#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")*s* are initialized as indicated by the corresponding[*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]") (which may be copy- or direct-initialization)[.](#lambda.capture-15.sentence-1) (For array members, the array elements are direct-initialized in increasing subscript order[.](#lambda.capture-15.sentence-2)) These initializations are performed in the (unspecified) order in which the non-static data members are declared[.](#lambda.capture-15.sentence-3) [*Note [9](#lambda.capture-note-9)*: This ensures that the destructions will occur in the reverse order of the constructions[.](#lambda.capture-15.sentence-4) — *end note*] [16](#lambda.capture-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3085) [*Note [10](#lambda.capture-note-10)*: If a non-reference entity is implicitly or explicitly captured by reference, invoking the function call operator of the corresponding [*lambda-expression*](#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") after the lifetime of the entity has ended is likely to result in undefined behavior[.](#lambda.capture-16.sentence-1) — *end note*] [17](#lambda.capture-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3092) A [*simple-capture*](#nt:simple-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") containing an ellipsis is a pack expansion ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#lambda.capture-17.sentence-1) An [*init-capture*](#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") containing an ellipsis is a pack expansion that declares an[*init-capture*](#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#lambda.capture-17.sentence-2) [*Example [12](#lambda.capture-example-12)*: templatevoid f(Args... args) {auto lm = [&, args...] { return g(args...); }; lm(); auto lm2 = [...xs=std::move(args)] { return g(xs...); }; lm2();} — *end example*] ### [7.5.7](#fold) Fold expressions [[expr.prim.fold]](expr.prim.fold) [1](#fold-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3116) A fold expression performs a fold of a pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates")) over a binary operator[.](#fold-1.sentence-1) [fold-expression:](#nt:fold-expression "7.5.7 Fold expressions [expr.prim.fold]") ( [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") ... ) ( ... [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") ) ( [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") ... [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") ) [fold-operator:](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") one of + - * / % ^ & | << >> += -= *= /= %= ^= &= |= <<= >>= = == != < > <= >= && || , .* ->* [2](#fold-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3136) An expression of the form(... *op* e) where *op* is a [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") is called a [*unary left fold*](#def:unary_left_fold "7.5.7 Fold expressions [expr.prim.fold]")[.](#fold-2.sentence-1) An expression of the form(e *op* ...) where *op* is a [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]") is called a [*unary right fold*](#def:unary_right_fold "7.5.7 Fold expressions [expr.prim.fold]")[.](#fold-2.sentence-2) Unary left folds and unary right folds are collectively called [*unary folds*](#def:unary_fold "7.5.7 Fold expressions [expr.prim.fold]")[.](#fold-2.sentence-3) In a unary fold, the [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") shall contain an unexpanded pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#fold-2.sentence-4) [3](#fold-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3152) An expression of the form(e1 *op1* ... *op2* e2) where *op1* and *op2* are [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]")*s* is called a [*binary fold*](#def:binary_fold "7.5.7 Fold expressions [expr.prim.fold]")[.](#fold-3.sentence-1) In a binary fold,*op1* and *op2* shall be the same [*fold-operator*](#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]"), and either e1 shall contain an unexpanded pack or e2 shall contain an unexpanded pack, but not both[.](#fold-3.sentence-2) If e2 contains an unexpanded pack, the expression is called a [*binary left fold*](#def:binary_left_fold "7.5.7 Fold expressions [expr.prim.fold]")[.](#fold-3.sentence-3) If e1 contains an unexpanded pack, the expression is called a [*binary right fold*](#def:binary_right_fold "7.5.7 Fold expressions [expr.prim.fold]")[.](#fold-3.sentence-4) [*Example [1](#fold-example-1)*: templatebool f(Args ...args) {return (true && ... && args); // OK}templatebool f(Args ...args) {return (args + ... + args); // error: both operands contain unexpanded packs} — *end example*] [4](#fold-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3184) A fold expression is a pack expansion[.](#fold-4.sentence-1) ### [7.5.8](#req) Requires expressions [[expr.prim.req]](expr.prim.req) #### [7.5.8.1](#req.general) General [[expr.prim.req.general]](expr.prim.req.general) [1](#req.general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3193) A [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") provides a concise way to express requirements on template arguments that can be checked by [name lookup](basic.lookup "6.5 Name lookup [basic.lookup]") or by checking properties of types and expressions[.](#req.general-1.sentence-1) [requires-expression:](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") requires [*requirement-parameter-list*](#nt:requirement-parameter-list "7.5.8.1 General [expr.prim.req.general]")opt [*requirement-body*](#nt:requirement-body "7.5.8.1 General [expr.prim.req.general]") [requirement-parameter-list:](#nt:requirement-parameter-list "7.5.8.1 General [expr.prim.req.general]") ( [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") ) [requirement-body:](#nt:requirement-body "7.5.8.1 General [expr.prim.req.general]") { [*requirement-seq*](#nt:requirement-seq "7.5.8.1 General [expr.prim.req.general]") } [requirement-seq:](#nt:requirement-seq "7.5.8.1 General [expr.prim.req.general]") [*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]") [*requirement-seq*](#nt:requirement-seq "7.5.8.1 General [expr.prim.req.general]")opt [requirement:](#nt:requirement "7.5.8.1 General [expr.prim.req.general]") [*simple-requirement*](#nt:simple-requirement "7.5.8.2 Simple requirements [expr.prim.req.simple]") [*type-requirement*](#nt:type-requirement "7.5.8.3 Type requirements [expr.prim.req.type]") [*compound-requirement*](#nt:compound-requirement "7.5.8.4 Compound requirements [expr.prim.req.compound]") [*nested-requirement*](#nt:nested-requirement "7.5.8.5 Nested requirements [expr.prim.req.nested]") [2](#req.general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3228) A [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") is a prvalue of type bool whose value is described below[.](#req.general-2.sentence-1) [3](#req.general-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3232) [*Example [1](#req.general-example-1)*: A common use of [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]")*s* is to define requirements in concepts such as the one below:templateconcept R = requires (T i) {typename T::type; {*i} -> std::[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]"); }; A [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") can also be used in a[*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") ([[temp.pre]](temp.pre "13.1 Preamble")) as a way of writing ad hoc constraints on template arguments such as the one below:templaterequires requires (T x) { x + x; } T add(T a, T b) { return a + b; } The first requires introduces the[*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]"), and the second introduces the [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]")[.](#req.general-3.sentence-3) — *end example*] [4](#req.general-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3256) A [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") may introduce local parameters using a[*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]")[.](#req.general-4.sentence-1) A local parameter of a [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") shall not have a default argument[.](#req.general-4.sentence-2) The type of such a parameter is determined as specified for a function parameter in [[dcl.fct]](dcl.fct "9.3.4.6 Functions")[.](#req.general-4.sentence-3) These parameters have no linkage, storage, or lifetime; they are only used as notation for the purpose of defining [*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]")*s*[.](#req.general-4.sentence-4) The [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") of a[*requirement-parameter-list*](#nt:requirement-parameter-list "7.5.8.1 General [expr.prim.req.general]") shall not terminate with an ellipsis[.](#req.general-4.sentence-5) [*Example [2](#req.general-example-2)*: templateconcept C = requires(T t, ...) { // error: terminates with an ellipsis t;};templateconcept C2 = requires(T p[2]) {(decltype(p))nullptr; // OK, p has type “pointer to T''}; — *end example*] [5](#req.general-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3281) The substitution of template arguments into a [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") can result in the formation of invalid types or expressions in the immediate context of its [*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]")*s* ([[temp.deduct.general]](temp.deduct.general "13.10.3.1 General")) or the violation of the semantic constraints of those [*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]")*s*[.](#req.general-5.sentence-1) In such cases, the [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") evaluates to false; it does not cause the program to be ill-formed[.](#req.general-5.sentence-2) The substitution and semantic constraint checking proceeds in lexical order and stops when a condition that determines the result of the [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") is encountered[.](#req.general-5.sentence-3) If substitution (if any) and semantic constraint checking succeed, the [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") evaluates to true[.](#req.general-5.sentence-4) [*Note [1](#req.general-note-1)*: If a [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") contains invalid types or expressions in its [*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]")*s*, and it does not appear within the declaration of a templated entity, then the program is ill-formed[.](#req.general-5.sentence-5) — *end note*] If the substitution of template arguments into a [*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]") would always result in a substitution failure, the program is ill-formed; no diagnostic required[.](#req.general-5.sentence-6) [*Example [3](#req.general-example-3)*: template concept C =requires {new decltype((void)T{}); // ill-formed, no diagnostic required}; — *end example*] #### [7.5.8.2](#req.simple) Simple requirements [[expr.prim.req.simple]](expr.prim.req.simple) [simple-requirement:](#nt:simple-requirement "7.5.8.2 Simple requirements [expr.prim.req.simple]") [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") ; [1](#req.simple-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3319) A [*simple-requirement*](#nt:simple-requirement "7.5.8.2 Simple requirements [expr.prim.req.simple]") asserts the validity of an [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]")[.](#req.simple-1.sentence-1) The [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") is an unevaluated operand[.](#req.simple-1.sentence-2) [*Note [1](#req.simple-note-1)*: The enclosing [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") will evaluate to false if substitution of template arguments into the [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") fails[.](#req.simple-1.sentence-3) — *end note*] [*Example [1](#req.simple-example-1)*: template concept C =requires (T a, T b) { a + b; // C is true if a + b is a valid expression}; — *end example*] [2](#req.simple-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3336) A [*requirement*](#nt:requirement "7.5.8.1 General [expr.prim.req.general]") that starts with a requires token is never interpreted as a [*simple-requirement*](#nt:simple-requirement "7.5.8.2 Simple requirements [expr.prim.req.simple]")[.](#req.simple-2.sentence-1) [*Note [2](#req.simple-note-2)*: This simplifies distinguishing between a [*simple-requirement*](#nt:simple-requirement "7.5.8.2 Simple requirements [expr.prim.req.simple]") and a [*nested-requirement*](#nt:nested-requirement "7.5.8.5 Nested requirements [expr.prim.req.nested]")[.](#req.simple-2.sentence-2) — *end note*] #### [7.5.8.3](#req.type) Type requirements [[expr.prim.req.type]](expr.prim.req.type) [type-requirement:](#nt:type-requirement "7.5.8.3 Type requirements [expr.prim.req.type]") typename [*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") ; typename [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") typename [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") [1](#req.type-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3354) A [*type-requirement*](#nt:type-requirement "7.5.8.3 Type requirements [expr.prim.req.type]") asserts the validity of a type[.](#req.type-1.sentence-1) The component names of a [*type-requirement*](#nt:type-requirement "7.5.8.3 Type requirements [expr.prim.req.type]") are those of its[*nested-name-specifier*](#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") (if any) and[*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") (if any)[.](#req.type-1.sentence-2) [*Note [1](#req.type-note-1)*: The enclosing [*requires-expression*](#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]") will evaluate to false if substitution of template arguments fails[.](#req.type-1.sentence-3) — *end note*] [*Example [1](#req.type-example-1)*: template struct S;template using Ref = T&; template concept C = requires {typename T::inner; // required nested member nametypename S; // required valid ([[temp.names]](temp.names "13.3 Names of template specializations")) [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]"); fails if T​::​type does not exist as a type// to which 0 can be implicitly convertedtypename Ref; // required alias template substitution, fails if T is voidtypename [:T::r1:]; // fails if T​::​r1 is not a reflection of a typetypename [:T::r2:]; // fails if T​::​r2 is not a reflection of a template Z for which Z is a type}; — *end example*] [2](#req.type-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3379) A [*type-requirement*](#nt:type-requirement "7.5.8.3 Type requirements [expr.prim.req.type]") that names a class template specialization does not require that type to be complete ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1 General"))[.](#req.type-2.sentence-1) #### [7.5.8.4](#req.compound) Compound requirements [[expr.prim.req.compound]](expr.prim.req.compound) [compound-requirement:](#nt:compound-requirement "7.5.8.4 Compound requirements [expr.prim.req.compound]") { [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") } noexceptopt [*return-type-requirement*](#nt:return-type-requirement "7.5.8.4 Compound requirements [expr.prim.req.compound]")opt ; [return-type-requirement:](#nt:return-type-requirement "7.5.8.4 Compound requirements [expr.prim.req.compound]") -> [*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]") [1](#req.compound-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3396) A [*compound-requirement*](#nt:compound-requirement "7.5.8.4 Compound requirements [expr.prim.req.compound]") asserts properties of the [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") E[.](#req.compound-1.sentence-1) The [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") is an unevaluated operand[.](#req.compound-1.sentence-2) Substitution of template arguments (if any) and verification of semantic properties proceed in the following order: - [(1.1)](#req.compound-1.1) Substitution of template arguments (if any) into the [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") is performed[.](#req.compound-1.1.sentence-1) - [(1.2)](#req.compound-1.2) If the noexcept specifier is present,E shall not be a potentially-throwing expression ([[except.spec]](except.spec "14.5 Exception specifications"))[.](#req.compound-1.2.sentence-1) - [(1.3)](#req.compound-1.3) If the [*return-type-requirement*](#nt:return-type-requirement "7.5.8.4 Compound requirements [expr.prim.req.compound]") is present, then: * [(1.3.1)](#req.compound-1.3.1) Substitution of template arguments (if any) into the [*return-type-requirement*](#nt:return-type-requirement "7.5.8.4 Compound requirements [expr.prim.req.compound]") is performed[.](#req.compound-1.3.1.sentence-1) * [(1.3.2)](#req.compound-1.3.2) The immediately-declared constraint ([[temp.param]](temp.param "13.2 Template parameters")) of the [*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]") for decltype((E)) shall be satisfied[.](#req.compound-1.3.2.sentence-1) [*Example [1](#req.compound-example-1)*: Given concepts C and D,requires {{ E1 } -> C; { E2 } -> D;}; is equivalent torequires { E1; requires C; E2; requires D;}; (including in the case where n is zero)[.](#req.compound-1.3.sentence-2) — *end example*] [2](#req.compound-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3442) [*Example [2](#req.compound-example-2)*: template concept C1 = requires(T x) {{x++};}; The [*compound-requirement*](#nt:compound-requirement "7.5.8.4 Compound requirements [expr.prim.req.compound]") in C1 requires that x++ is a valid expression[.](#req.compound-2.sentence-1) It is equivalent to the [*simple-requirement*](#nt:simple-requirement "7.5.8.2 Simple requirements [expr.prim.req.simple]")x++;[.](#req.compound-2.sentence-2) template concept C2 = requires(T x) {{*x} -> std::[same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]");}; The [*compound-requirement*](#nt:compound-requirement "7.5.8.4 Compound requirements [expr.prim.req.compound]") in C2 requires that *x is a valid expression, that typename T​::​inner is a valid type, and that std​::​[same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]") is satisfied[.](#req.compound-2.sentence-3) template concept C3 =requires(T x) {{g(x)} noexcept; }; The [*compound-requirement*](#nt:compound-requirement "7.5.8.4 Compound requirements [expr.prim.req.compound]") in C3 requires that g(x) is a valid expression and that g(x) is non-throwing[.](#req.compound-2.sentence-4) — *end example*] #### [7.5.8.5](#req.nested) Nested requirements [[expr.prim.req.nested]](expr.prim.req.nested) [nested-requirement:](#nt:nested-requirement "7.5.8.5 Nested requirements [expr.prim.req.nested]") requires [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") ; [1](#req.nested-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3485) A [*nested-requirement*](#nt:nested-requirement "7.5.8.5 Nested requirements [expr.prim.req.nested]") can be used to specify additional constraints in terms of local parameters[.](#req.nested-1.sentence-1) The [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") shall be satisfied ([[temp.constr.decl]](temp.constr.decl "13.5.3 Constrained declarations")) by the substituted template arguments, if any[.](#req.nested-1.sentence-2) Substitution of template arguments into a [*nested-requirement*](#nt:nested-requirement "7.5.8.5 Nested requirements [expr.prim.req.nested]") does not result in substitution into the [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") other than as specified in [[temp.constr.constr]](temp.constr.constr "13.5.2 Constraints")[.](#req.nested-1.sentence-3) [*Example [1](#req.nested-example-1)*: template concept C = sizeof(U) == 1; template concept D = requires (T t) {requires C;};D is satisfied if sizeof(decltype (+t)) == 1 ([[temp.constr.atomic]](temp.constr.atomic "13.5.2.3 Atomic constraints"))[.](#req.nested-1.sentence-4) — *end example*] ### [7.5.9](#splice) Expression splicing [[expr.prim.splice]](expr.prim.splice) [splice-expression:](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") template [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") template [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") [1](#splice-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3516) A [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") or [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") immediately followed by ​::​ or preceded by typename is never interpreted as part of a [*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]")[.](#splice-1.sentence-1) [*Example [1](#splice-example-1)*: struct S { static constexpr int a = 1; };template struct TCls { static constexpr int b = 2; }; constexpr int c = [:^^S:]::a; // OK, [:^^S:] is not an expressionconstexpr int d = template [:^^TCls:]::b; // OK, template [:^^TCls:] is not an expressiontemplate constexpr int e = [:V:]; // OKconstexpr int f = template [:^^e:]<^^S::a>; // OKconstexpr auto g = typename [:^^int:](42); // OK, typename [:^^int:] is a [*splice-type-specifier*](dcl.type.splice#nt:splice-type-specifier "9.2.9.9 Type splicing [dcl.type.splice]")constexpr auto h = ^^g;constexpr auto i = e<[:^^h:]>; // error: unparenthesized [*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") used as template argumentconstexpr auto j = e<([:^^h:])>; // OK — *end example*] [2](#splice-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3539) For a [*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") of the form [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]"), let S be the construct designated by [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]")[.](#splice-2.sentence-1) - [(2.1)](#splice-2.1) The expression is ill-formed if S is * [(2.1.1)](#splice-2.1.1) a constructor, * [(2.1.2)](#splice-2.1.2) a destructor, * [(2.1.3)](#splice-2.1.3) an unnamed bit-field, or * [(2.1.4)](#splice-2.1.4) a local entity ([[basic.pre]](basic.pre "6.1 Preamble")) such that + [(2.1.4.1)](#splice-2.1.4.1) there is a lambda scope that intervenes between the expression and the point at which S was introduced and + [(2.1.4.2)](#splice-2.1.4.2) the expression would be potentially evaluated if the effect of any enclosing typeid expressions ([[expr.typeid]](expr.typeid "7.6.1.8 Type identification")) were ignored[.](#splice-2.1.sentence-1) - [(2.2)](#splice-2.2) Otherwise, if S is a function F, the expression denotes an overload set containing all declarations of F that precede either the expression or the point immediately following the [*class-specifier*](class.pre#nt:class-specifier "11.1 Preamble [class.pre]") of the outermost class for which the expression is in a complete-class context; overload resolution is performed ([[over.match]](over.match "12.2 Overload resolution"), [[over.over]](over.over "12.3 Address of an overload set"))[.](#splice-2.2.sentence-1) - [(2.3)](#splice-2.3) Otherwise, if S is an object or a non-static data member, the expression is an lvalue designating S[.](#splice-2.3.sentence-1) The expression has the same type as that of S, and is a bit-field if and only if S is a bit-field[.](#splice-2.3.sentence-2) [*Note [1](#splice-note-1)*: The implicit transformation whereby an [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") denoting a non-static member becomes a class member access ([[expr.prim.id]](#id "7.5.5 Names")) does not apply to a [*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]")[.](#splice-2.3.sentence-3) — *end note*] - [(2.4)](#splice-2.4) Otherwise, if S is a variable or a structured binding,S shall either have static or thread storage duration or shall inhabit a scope enclosing the expression[.](#splice-2.4.sentence-1) The expression is an lvalue referring to the object or function X associated with or referenced by S, has the same type as that of S, and is a bit-field if and only if X is a bit-field[.](#splice-2.4.sentence-2) [*Note [2](#splice-note-2)*: The type of a [*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") designating a variable or structured binding of reference type will be adjusted to a non-reference type ([[expr.type]](expr.type "7.2.2 Type"))[.](#splice-2.4.sentence-3) — *end note*] - [(2.5)](#splice-2.5) Otherwise, if S is a value or an enumerator, the expression is a prvalue that computes S and whose type is the same as that of S[.](#splice-2.5.sentence-1) - [(2.6)](#splice-2.6) Otherwise, the expression is ill-formed[.](#splice-2.6.sentence-1) [3](#splice-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3603) For a [*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") of the form template [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]"), the [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") shall designate a function template T that is not a constructor template[.](#splice-3.sentence-1) The expression denotes an overload set containing all declarations of T that precede either the expression or the point immediately following the [*class-specifier*](class.pre#nt:class-specifier "11.1 Preamble [class.pre]") of the outermost class for which the expression is in a complete-class context; overload resolution is performed[.](#splice-3.sentence-2) [*Note [3](#splice-note-3)*: During overload resolution, candidate function templates undergo template argument deduction and the resulting specializations are considered as candidate functions[.](#splice-3.sentence-3) — *end note*] [4](#splice-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L3619) For a [*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") of the form template [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]"), the [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") of the [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") shall designate a template T[.](#splice-4.sentence-1) - [(4.1)](#splice-4.1) If T is a function template, the expression denotes an overload set containing all declarations of T that precede either the expression or the point immediately following the [*class-specifier*](class.pre#nt:class-specifier "11.1 Preamble [class.pre]") of the outermost class for which the expression is in a complete-class context; overload resolution is performed ([[over.match]](over.match "12.2 Overload resolution"), [[over.over]](over.over "12.3 Address of an overload set"))[.](#splice-4.1.sentence-1) - [(4.2)](#splice-4.2) Otherwise, if T is a variable template, let S be the specialization of T corresponding to the template argument list of the [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]")[.](#splice-4.2.sentence-1) The expression is an lvalue referring to the object associated with S and has the same type as that of S[.](#splice-4.2.sentence-2) - [(4.3)](#splice-4.3) Otherwise, the expression is ill-formed[.](#splice-4.3.sentence-1) [*Note [4](#splice-note-4)*: Class members are accessible from any point when designated by [*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]")*s* ([[class.access.base]](class.access.base "11.8.3 Accessibility of base classes and base class members"))[.](#splice-4.sentence-2) A class member access expression ([[expr.ref]](expr.ref "7.6.1.5 Class member access")) whose right operand is a [*splice-expression*](#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") is ill-formed if the left operand (considered as a pointer) cannot be implicitly converted to a pointer to the designating class of the right operand[.](#splice-4.sentence-3) — *end note*]