[expr.prim.lambda]

# 7 Expressions [[expr]](./#expr)

## 7.5 Primary expressions [[expr.prim]](expr.prim#lambda)

### 7.5.6 Lambda expressions [expr.prim.lambda]

#### [7.5.6.1](#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](#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[.](#general-1.sentence-1)

[*Example [1](#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](#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]")[.](#general-2.sentence-1)

[*Note [1](#general-note-1)*:

A closure object behaves like a [function
object](function.objects "22.10 Function objects [function.objects]")[.](#general-2.sentence-2)

â *end note*]

[3](#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]")[.](#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]")[.](#general-3.sentence-2)

[*Note [2](#general-note-2)*:

Such ambiguous cases cannot have valid semantics
because the constraint expression would not have type bool[.](#general-3.sentence-3)

[*Example [2](#general-example-2)*: auto x = []<class T> requires T::operator int [[some_attribute]] (int) { } â *end example*]

â *end note*]

[4](#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[.](#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[.](#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[.](#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]")[.](#general-4.sentence-4)

[*Note [3](#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")[.](#general-4.sentence-5)

â *end note*]

[5](#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[.](#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[.](#general-5.sentence-2)

[*Note [4](#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")[.](#general-5.sentence-3)

â *end note*]

[*Example [3](#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](#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]")[.](#general-6.sentence-1)

[*Example [4](#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](#closure) Closure types [[expr.prim.lambda.closure]](expr.prim.lambda.closure)

[1](#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[.](#closure-1.sentence-1)

[2](#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]")[.](#closure-2.sentence-1)

[3](#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]")[.](#closure-3.sentence-1)

[*Note [1](#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"))[.](#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[.](#closure-3.sentence-3)

â *end note*]

[4](#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]")[.](#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)](#closure-4.1)

the size and/or alignment of the closure type,

- [(4.2)](#closure-4.2)

whether the closure type is trivially copyable ([[class.prop]](class.prop "11.2 Properties of classes")),

- [(4.3)](#closure-4.3)

whether the closure type is trivially relocatable ([[class.prop]](class.prop "11.2 Properties of classes")),

- [(4.4)](#closure-4.4)

whether the closure type is replaceable ([[class.prop]](class.prop "11.2 Properties of classes")), or

- [(4.5)](#closure-4.5)

whether the closure type is a standard-layout class ([[class.prop]](class.prop "11.2 Properties of classes"))[.](#closure-4.sentence-2)

An implementation shall not add members of rvalue reference type to the closure
type[.](#closure-4.sentence-3)

[5](#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[.](#closure-5.sentence-1)

The function call operator or the function call operator template are
direct members of the closure type[.](#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[.](#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[.](#closure-5.sentence-4)

[*Note [2](#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"))[.](#closure-5.sentence-5)

â *end note*]

[*Example [1](#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](#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)](#closure-6.1)

the closure type,

- [(6.2)](#closure-6.2)

a class type publicly and unambiguously derived from the closure type, or

- [(6.3)](#closure-6.3)

a reference to a possibly cv-qualified such type[.](#closure-6.sentence-1)

[*Example [2](#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](#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[.](#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[.](#closure-7.sentence-2)

It is neither virtual nor declared volatile[.](#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[.](#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[.](#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[.](#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"))[.](#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[.](#closure-7.sentence-8)

[*Example [3](#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](#closure-8)

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

[*Example [4](#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](#closure-9)

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

[*Note [3](#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"))[.](#closure-9.sentence-1)

[*Example [5](#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](#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[.](#closure-10.sentence-1)

[*Note [4](#closure-note-4)*:

Adding a contract assertion to an existing C++ program cannot
cause additional captures[.](#closure-10.sentence-2)

â *end note*]

[*Example [6](#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](#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[.](#closure-11.sentence-1)

The conversion is to âpointer to noexcept functionâ
if the function call operator
has a non-throwing exception specification[.](#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[.](#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[.](#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[.](#closure-11.sentence-5)

[12](#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[.](#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[.](#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[.](#closure-12.sentence-3)

[13](#closure-13)

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

[*Note [5](#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[.](#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[.](#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](#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](#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[.](#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[.](#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[.](#closure-14.sentence-3)

[*Note [6](#closure-note-6)*:

This will result in the implicit instantiation of the generic lambda's body[.](#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[.](#closure-14.sentence-5)

â *end note*]

[*Example [8](#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](#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]")[.](#closure-15.sentence-1)

[*Example [9](#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](#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[.](#closure-16.sentence-1)

[*Example [10](#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")[.](#closure-16.sentence-2)

[17](#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[.](#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"))[.](#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"))[.](#closure-17.sentence-3)

[*Note [7](#closure-note-7)*:

These special member functions are implicitly defined as
usual, which can result in them being defined as deleted[.](#closure-17.sentence-4)

â *end note*]

[18](#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"))[.](#closure-18.sentence-1)

[19](#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]")[.](#closure-19.sentence-1)

#### [7.5.6.3](#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](#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[.](#capture-1.sentence-1)

[2](#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 &[.](#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â[.](#capture-2.sentence-2)

[*Note [1](#capture-note-1)*:

The form [&,this] is redundant but accepted
for compatibility with C++ 2014[.](#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]")[.](#capture-2.sentence-4)

[*Example [1](#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](#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)](#capture-3.1)

its innermost enclosing scope is a block scope ([[basic.scope.block]](basic.scope.block "6.4.3 Block scope")),

- [(3.2)](#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)](#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"))[.](#capture-3.sentence-1)

[4](#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"))[.](#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[.](#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]")[.](#capture-4.sentence-3)

[5](#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[.](#capture-5.sentence-1)

[*Example [2](#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](#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]")[.](#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)](#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)](#capture-6.2)

if the capture is by reference, the variable's lifetime ends when the
closure object's lifetime ends[.](#capture-6.sentence-2)

[*Note [2](#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[.](#capture-6.sentence-3)

â *end note*]

[*Example [3](#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](#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)](#capture-7.1)

  An [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") that names a local entity
potentially references that entity;
an [*id-expression*](expr.prim.id.general#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[.](#capture-7.1.sentence-1)
  [*Note [3](#capture-note-3)*:
  This occurs even if overload resolution
selects a static member function for the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]")[.](#capture-7.1.sentence-2)
 â *end note*]

- [(7.2)](#capture-7.2)

  A this expression potentially references *this[.](#capture-7.2.sentence-1)

- [(7.3)](#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*[.](#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[.](#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")[.](#capture-7.sentence-3)

[*Example [4](#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[.](#capture-7.sentence-4)

â *end example*]

[*Note [4](#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"))[.](#capture-7.sentence-5)

[*Example [5](#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](#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[.](#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]")[.](#capture-8.sentence-2)

[*Note [5](#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"))[.](#capture-8.sentence-3)

â *end note*]

[*Example [6](#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](#capture-9)

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

[*Note [6](#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[.](#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"))[.](#capture-9.sentence-2)

â *end note*]

[*Example [7](#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](#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)](#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)](#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]")[.](#capture-10.sentence-1)

For each entity captured by copy, an
unnamed non-static data member is declared in the closure type[.](#capture-10.sentence-2)

The declaration order of
these members is unspecified[.](#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[.](#capture-10.sentence-4)

A member of an anonymous union shall not be captured by copy[.](#capture-10.sentence-5)

[11](#capture-11)

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

Every [*id-expression*](expr.prim.id.general#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[.](#capture-11.sentence-1)

[*Note [7](#capture-note-7)*:

An [*id-expression*](expr.prim.id.general#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[.](#capture-11.sentence-2)

However, such
an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") can still cause the implicit capture of the
entity[.](#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[.](#capture-11.sentence-4)

[*Example [8](#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](#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[.](#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[.](#capture-12.sentence-2)

If declared, such non-static data members shall be of literal type[.](#capture-12.sentence-3)

[*Example [9](#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[.](#capture-12.sentence-4)

[13](#capture-13)

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

An [*id-expression*](expr.prim.id.general#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[.](#capture-13.sentence-1)

[*Note [8](#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[.](#capture-13.sentence-2)

â *end note*]

[*Example [10](#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](#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)](#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[.](#capture-14.1.sentence-1)

- [(14.2)](#capture-14.2)

  If m1 captures the entity by reference,m2 captures the same
entity captured by m1[.](#capture-14.2.sentence-1)

[*Example [11](#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[.](#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](#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)[.](#capture-15.sentence-1)

(For array members, the array elements are
direct-initialized in increasing subscript order[.](#capture-15.sentence-2))

These initializations are performed
in the (unspecified) order in which the non-static data members are declared[.](#capture-15.sentence-3)

[*Note [9](#capture-note-9)*:

This ensures that the destructions will occur in the reverse order of the constructions[.](#capture-15.sentence-4)

â *end note*]

[16](#capture-16)

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

[*Note [10](#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[.](#capture-16.sentence-1)

â *end note*]

[17](#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"))[.](#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"))[.](#capture-17.sentence-2)

[*Example [12](#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*]
