[expr.prim.lambda.closure]

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

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

### 7.5.6 Lambda expressions [[expr.prim.lambda]](expr.prim.lambda#closure)

#### 7.5.6.2 Closure types [expr.prim.lambda.closure]

[1](#1)

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

The type of a [*lambda-expression*](expr.prim.lambda.general#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[.](#1.sentence-1)

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

[3](#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*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")[.](#3.sentence-1)

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

The parameter
types of a [*lambda-declarator*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") do not affect these associated namespaces and
classes[.](#3.sentence-3)

â *end note*]

[4](#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*](expr.prim.lambda.capture#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")[.](#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)](#4.1)

the size and/or alignment of the closure type,

- [(4.2)](#4.2)

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

- [(4.3)](#4.3)

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

- [(4.4)](#4.4)

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

- [(4.5)](#4.5)

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

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

[5](#5)

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

The closure type for a [*lambda-expression*](expr.prim.lambda.general#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*](expr.prim.lambda.general#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[.](#5.sentence-1)

The function call operator or the function call operator template are
direct members of the closure type[.](#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[.](#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*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]"), if any[.](#5.sentence-4)

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

â *end note*]

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

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

Given a lambda with a [*lambda-capture*](expr.prim.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)](#6.1)

the closure type,

- [(6.2)](#6.2)

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

- [(6.3)](#6.3)

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

[*Example [2](#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](#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*](expr.prim.lambda.general#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[.](#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*](expr.prim.lambda.general#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*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") does not contain
an explicit object parameter[.](#7.sentence-2)

It is neither virtual nor declared volatile[.](#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*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") applies to the corresponding function call operator or operator template[.](#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*](expr.prim.lambda.general#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[.](#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*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") preceding a [*lambda-declarator*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") appertains to the corresponding function call operator or operator template[.](#7.sentence-6)

The function call operator or any given operator template specialization
is a constexpr function if either
the corresponding [*lambda-expression*](expr.prim.lambda.general#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"))[.](#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*](expr.prim.lambda.general#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[.](#7.sentence-8)

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

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

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

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

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

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

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

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

â *end note*]

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

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

The closure type for a non-generic [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") with no[*lambda-capture*](expr.prim.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[.](#11.sentence-1)

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

[12](#12)

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

For a generic lambda with no [*lambda-capture*](expr.prim.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[.](#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[.](#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[.](#12.sentence-3)

[13](#13)

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

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

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

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

â *end note*]

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

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

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

The [*lambda-expression*](expr.prim.lambda.general#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[.](#16.sentence-1)

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

[17](#17)

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

The closure type associated with a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") has no
default constructor
if the [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") has a [*lambda-capture*](expr.prim.lambda.capture#nt:lambda-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") and a defaulted default constructor otherwise[.](#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"))[.](#17.sentence-2)

It has a deleted copy assignment operator if the [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") has a [*lambda-capture*](expr.prim.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"))[.](#17.sentence-3)

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

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

â *end note*]

[18](#18)

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

The closure type associated with a [*lambda-expression*](expr.prim.lambda.general#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"))[.](#18.sentence-1)

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