[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<class T> 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<typename T> struct A {static void f(int) requires false;};

void g() { A<int>::f(0); // error: cannot call fvoid (*p1)(int) = A<int>::f; // error: cannot take the address of fdecltype(A<int>::f)* p2 = nullptr; // error: the type decltype(A<int>​::​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 <int N, int& R, int* P>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)*: template<int V>struct 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â¤V<sizeof...(P)[.](#pack.index-2.sentence-1)

[3](#pack.index-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2020)

A [*pack-index-expression*](#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]") is a pack expansion ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#pack.index-3.sentence-1)

[4](#pack.index-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2023)

[*Note [1](#pack.index-note-1)*:

A [*pack-index-expression*](#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]") denotes
the Vth element of the pack[.](#pack.index-4.sentence-1)

â *end note*]

#### [7.5.5.5](#id.dtor) Destruction [[expr.prim.id.dtor]](expr.prim.id.dtor)

[1](#id.dtor-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2031)

An [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") that denotes the destructor of a type T names the destructor of T if T is a class type ([[class.dtor]](class.dtor "11.4.7 Destructors")),
otherwise the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is said
to name a [*pseudo-destructor*](#def:pseudo-destructor "7.5.5.5 Destruction [expr.prim.id.dtor]")[.](#id.dtor-1.sentence-1)

[2](#id.dtor-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2040)

If the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") names a pseudo-destructor,T shall be a scalar type and
the [*id-expression*](#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") shall appear
as the right operand of a class member access ([[expr.ref]](expr.ref "7.6.1.5 Class member access")) that forms
the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") of a function call ([[expr.call]](expr.call "7.6.1.3 Function call"))[.](#id.dtor-2.sentence-1)

[*Note [1](#id.dtor-note-1)*:

Such a call ends the lifetime of the object ([[expr.call]](expr.call "7.6.1.3 Function call"), [[basic.life]](basic.life "6.8.4 Lifetime"))[.](#id.dtor-2.sentence-2)

â *end note*]

[3](#id.dtor-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L2050)

[*Example [1](#id.dtor-example-1)*: struct C { };void f() { C * pc = new C; using C2 = C;
 pc->C::~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 <algorithm>#include <cmath>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 = []<class T> 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 = []<class T>(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<decltype(ts)>(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 <typename T> 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 <typename T> concept C1 = /* ... */;template <std::size_t N> concept C2 = /* ... */;template <typename A, typename B> concept C3 = /* ... */;

auto f = []<typename T1, C1 T2> requires C2<sizeof(T1) + sizeof(T2)>(T1 a1, T1 b1, T2 a2, auto a3, auto a4) requires C3<decltype(a4), T2> {// 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<class T> auto operator()(T t) const { /* ... */ }template<class T> static auto lambda_call_operator_invoker(T a) {// forwards execution to operator()(a) and therefore has// the same return type deduced/* ... */}template<class T> using fptr_t =decltype(lambda_call_operator_invoker(declval<T>())) (*)(T); template<class T> operator fptr_t<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]<typename y>(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)*: template<bool B>void 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)*: template<class... Args>void 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)*: template<typename ...Args>bool f(Args ...args) {return (true && ... && args); // OK}template<typename ...Args>bool 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:template<typename T>concept R = requires (T i) {typename T::type; {*i} -> std::[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<const typename T::type&>; };

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:template<typename T>requires 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)*: template<typename T>concept C = requires(T t, ...) { // error: terminates with an ellipsis t;};template<typename T>concept 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<typename T> 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<typename T> concept C =requires (T a, T b) { a + b; // C<T> 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<typename T, typename T::type = 0> struct S;template<typename T> using Ref = T&;

template<typename T> concept C = requires {typename T::inner; // required nested member nametypename S<T>; // 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<T>; // required alias template substitution, fails if T is voidtypename [:T::r1:]; // fails if T​::​r1 is not a reflection of a typetypename [:T::r2:]<int>; // fails if T​::​r2 is not a reflection of a template Z for which Z<int> 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<A1, â¯, An>;}; is equivalent torequires { E1; requires C<decltype((E1))>;
 E2; requires D<decltype((E2)), A1, â¯, An>;}; (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<typename T> 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<typename T> concept C2 = requires(T x) {{*x} -> std::[same_as](concept.same#concept:same_as "18.4.2 Concept same_­as [concept.same]")<typename T::inner>;};

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]")<decltype((*x)), typename T​::​inner> is satisfied[.](#req.compound-2.sentence-3)

template<typename T> 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<typename U> concept C = sizeof(U) == 1;

template<typename T> concept D = requires (T t) {requires C<decltype (+t)>;};D<T> 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<typename> struct TCls { static constexpr int b = 2; };

constexpr int c = [:^^S:]::a; // OK, [:^^S:] is not an expressionconstexpr int d = template [:^^TCls:]<int>::b; // OK, template [:^^TCls:]<int> is not an expressiontemplate<auto V> 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*]
