- tmp/tmp2kqlkgff/{from.md → to.md} +268 -100
tmp/tmp2kqlkgff/{from.md → to.md}
RENAMED
|
@@ -43,39 +43,54 @@ capture-list:
|
|
| 43 |
capture-list ',' capture '...'ₒₚₜ
|
| 44 |
```
|
| 45 |
|
| 46 |
``` bnf
|
| 47 |
capture:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
identifier
|
| 49 |
'&' identifier
|
| 50 |
'this'
|
| 51 |
```
|
| 52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
``` bnf
|
| 54 |
lambda-declarator:
|
| 55 |
'(' parameter-declaration-clause ')' 'mutable'ₒₚₜ
|
| 56 |
exception-specificationₒₚₜ attribute-specifier-seqₒₚₜ trailing-return-typeₒₚₜ
|
| 57 |
```
|
| 58 |
|
| 59 |
The evaluation of a *lambda-expression* results in a prvalue temporary (
|
| 60 |
[[class.temporary]]). This temporary is called the *closure object*. A
|
| 61 |
*lambda-expression* shall not appear in an unevaluated operand (Clause
|
| 62 |
-
[[expr]])
|
| 63 |
-
|
|
|
|
|
|
|
|
|
|
| 64 |
|
| 65 |
The type of the *lambda-expression* (which is also the type of the
|
| 66 |
closure object) is a unique, unnamed non-union class type — called the
|
| 67 |
*closure type* — whose properties are described below. This class type
|
| 68 |
-
is
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
[[basic.lookup.argdep]]). The
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
other than by changing:
|
| 77 |
|
| 78 |
- the size and/or alignment of the closure type,
|
| 79 |
- whether the closure type is trivially copyable (Clause [[class]]),
|
| 80 |
- whether the closure type is a standard-layout class (Clause
|
| 81 |
[[class]]), or
|
|
@@ -83,52 +98,145 @@ other than by changing:
|
|
| 83 |
|
| 84 |
An implementation shall not add members of rvalue reference type to the
|
| 85 |
closure type.
|
| 86 |
|
| 87 |
If a *lambda-expression* does not include a *lambda-declarator*, it is
|
| 88 |
-
as if the *lambda-declarator* were `()`.
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
- if the *compound-statement* is of the form
|
| 93 |
-
``` bnf
|
| 94 |
-
'{' attribute-specifier-seqₒₚₜ 'return' expression ';' '}'
|
| 95 |
-
```
|
| 96 |
-
|
| 97 |
-
the type of the returned expression after lvalue-to-rvalue
|
| 98 |
-
conversion ([[conv.lval]]), array-to-pointer conversion (
|
| 99 |
-
[[conv.array]]), and function-to-pointer conversion ([[conv.func]]);
|
| 100 |
-
- otherwise, `void`.
|
| 101 |
|
| 102 |
``` cpp
|
| 103 |
auto x1 = [](int i){ return i; }; // OK: return type is int
|
| 104 |
-
auto x2 = []{ return { 1, 2 }; };
|
| 105 |
-
|
|
|
|
| 106 |
```
|
| 107 |
|
| 108 |
-
The closure type for a *lambda-expression* has a public
|
| 109 |
-
function call operator ([[over.call]]) whose parameters and
|
| 110 |
-
are described by the *lambda-expression*’s
|
| 111 |
*parameter-declaration-clause* and *trailing-return-type* respectively.
|
| 112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 113 |
[[class.mfct.non-static]]) if and only if the *lambda-expression*’s
|
| 114 |
*parameter-declaration-clause* is not followed by `mutable`. It is
|
| 115 |
-
neither virtual nor declared `volatile`.
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
*
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
|
| 131 |
The *lambda-expression*’s *compound-statement* yields the
|
| 132 |
*function-body* ([[dcl.fct.def]]) of the function call operator, but
|
| 133 |
for purposes of name lookup ([[basic.lookup]]), determining the type
|
| 134 |
and value of `this` ([[class.this]]) and transforming *id-expression*s
|
|
@@ -148,16 +256,21 @@ struct S1 {
|
|
| 148 |
};
|
| 149 |
}
|
| 150 |
};
|
| 151 |
```
|
| 152 |
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 159 |
|
| 160 |
``` cpp
|
| 161 |
struct S2 { void f(int i); };
|
| 162 |
void S2::f(int i) {
|
| 163 |
[&, i]{ }; // OK
|
|
@@ -166,40 +279,89 @@ void S2::f(int i) {
|
|
| 166 |
[i, i]{ }; // error: i repeated
|
| 167 |
}
|
| 168 |
```
|
| 169 |
|
| 170 |
A *lambda-expression* whose smallest enclosing scope is a block scope (
|
| 171 |
-
[[basic.scope.
|
| 172 |
-
*lambda-expression* shall not have a *capture-
|
| 173 |
-
*lambda-introducer*. The *reaching scope* of a
|
| 174 |
-
is the set of enclosing scopes up to and
|
| 175 |
-
enclosing function and its parameters. This
|
| 176 |
-
intervening *lambda-expression*s.
|
| 177 |
|
| 178 |
-
The *
|
| 179 |
rules for unqualified name lookup ([[basic.lookup.unqual]]); each such
|
| 180 |
-
lookup shall find
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
the
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
*
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 194 |
|
| 195 |
An entity is *captured* if it is captured explicitly or implicitly. An
|
| 196 |
entity captured by a *lambda-expression* is odr-used (
|
| 197 |
[[basic.def.odr]]) in the scope containing the *lambda-expression*. If
|
| 198 |
`this` is captured by a local lambda expression, its nearest enclosing
|
| 199 |
function shall be a non-static member function. If a *lambda-expression*
|
| 200 |
-
|
|
|
|
| 201 |
storage duration from its reaching scope, that entity shall be captured
|
| 202 |
by the *lambda-expression*. If a *lambda-expression* captures an entity
|
| 203 |
and that entity is not defined or captured in the immediately enclosing
|
| 204 |
lambda expression or function, the program is ill-formed.
|
| 205 |
|
|
@@ -249,22 +411,25 @@ void f2() {
|
|
| 249 |
}
|
| 250 |
```
|
| 251 |
|
| 252 |
An entity is *captured by copy* if it is implicitly captured and the
|
| 253 |
*capture-default* is `=` or if it is explicitly captured with a capture
|
| 254 |
-
that
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
otherwise. If the captured entity is a
|
| 260 |
-
corresponding data member is also a
|
|
|
|
|
|
|
| 261 |
|
| 262 |
An entity is *captured by reference* if it is implicitly or explicitly
|
| 263 |
captured but not captured by copy. It is unspecified whether additional
|
| 264 |
unnamed non-static data members are declared in the closure type for
|
| 265 |
-
entities captured by reference.
|
|
|
|
| 266 |
|
| 267 |
If a *lambda-expression* `m2` captures an entity and that entity is
|
| 268 |
captured by an immediately enclosing *lambda-expression* `m1`, then
|
| 269 |
`m2`’s capture is transformed as follows:
|
| 270 |
|
|
@@ -289,30 +454,30 @@ auto m1 = [a, &b, &c]() mutable {
|
|
| 289 |
a = 2; b = 2; c = 2;
|
| 290 |
m1();
|
| 291 |
std::cout << a << b << c;
|
| 292 |
```
|
| 293 |
|
| 294 |
-
Every *id-expression*
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
*id-expression* that is not
|
| 298 |
-
|
| 299 |
-
*id-expression* does not cause the
|
| 300 |
-
`this` is captured, each odr-use of
|
| 301 |
-
|
| 302 |
-
[[expr.cast]]) to the type of `this`.
|
| 303 |
-
transformed expression is a prvalue.
|
| 304 |
|
| 305 |
``` cpp
|
| 306 |
void f(const int*);
|
| 307 |
void g() {
|
| 308 |
const int N = 10;
|
| 309 |
[=] {
|
| 310 |
int arr[N]; // OK: not an odr-use, refers to automatic variable
|
| 311 |
f(&N); // OK: causes N to be captured; &N points to the
|
| 312 |
// corresponding member of the closure type
|
| 313 |
-
}
|
| 314 |
}
|
| 315 |
```
|
| 316 |
|
| 317 |
Every occurrence of `decltype((x))` where `x` is a possibly
|
| 318 |
parenthesized *id-expression* that names an entity of automatic storage
|
|
@@ -344,24 +509,27 @@ implicitly defined.
|
|
| 344 |
The closure type associated with a *lambda-expression* has an
|
| 345 |
implicitly-declared destructor ([[class.dtor]]).
|
| 346 |
|
| 347 |
When the *lambda-expression* is evaluated, the entities that are
|
| 348 |
captured by copy are used to direct-initialize each corresponding
|
| 349 |
-
non-static data member of the resulting closure object
|
| 350 |
-
|
| 351 |
-
|
| 352 |
-
|
| 353 |
-
|
| 354 |
-
the
|
|
|
|
|
|
|
| 355 |
|
| 356 |
If an entity is implicitly or explicitly captured by reference, invoking
|
| 357 |
the function call operator of the corresponding *lambda-expression*
|
| 358 |
after the lifetime of the entity has ended is likely to result in
|
| 359 |
undefined behavior.
|
| 360 |
|
| 361 |
-
A *capture* followed by an ellipsis is a pack expansion (
|
| 362 |
-
[[temp.variadic]]).
|
|
|
|
| 363 |
|
| 364 |
``` cpp
|
| 365 |
template<class... Args>
|
| 366 |
void f(Args... args) {
|
| 367 |
auto lm = [&, args...] { return g(args...); };
|
|
|
|
| 43 |
capture-list ',' capture '...'ₒₚₜ
|
| 44 |
```
|
| 45 |
|
| 46 |
``` bnf
|
| 47 |
capture:
|
| 48 |
+
simple-capture
|
| 49 |
+
init-capture
|
| 50 |
+
```
|
| 51 |
+
|
| 52 |
+
``` bnf
|
| 53 |
+
simple-capture:
|
| 54 |
identifier
|
| 55 |
'&' identifier
|
| 56 |
'this'
|
| 57 |
```
|
| 58 |
|
| 59 |
+
``` bnf
|
| 60 |
+
init-capture:
|
| 61 |
+
identifier initializer
|
| 62 |
+
'&' identifier initializer
|
| 63 |
+
```
|
| 64 |
+
|
| 65 |
``` bnf
|
| 66 |
lambda-declarator:
|
| 67 |
'(' parameter-declaration-clause ')' 'mutable'ₒₚₜ
|
| 68 |
exception-specificationₒₚₜ attribute-specifier-seqₒₚₜ trailing-return-typeₒₚₜ
|
| 69 |
```
|
| 70 |
|
| 71 |
The evaluation of a *lambda-expression* results in a prvalue temporary (
|
| 72 |
[[class.temporary]]). This temporary is called the *closure object*. A
|
| 73 |
*lambda-expression* shall not appear in an unevaluated operand (Clause
|
| 74 |
+
[[expr]]), in a *template-argument*, in an *alias-declaration*, in a
|
| 75 |
+
typedef declaration, or in the declaration of a function or function
|
| 76 |
+
template outside its function body and default arguments. The intention
|
| 77 |
+
is to prevent lambdas from appearing in a signature. A closure object
|
| 78 |
+
behaves like a function object ([[function.objects]]).
|
| 79 |
|
| 80 |
The type of the *lambda-expression* (which is also the type of the
|
| 81 |
closure object) is a unique, unnamed non-union class type — called the
|
| 82 |
*closure type* — whose properties are described below. This class type
|
| 83 |
+
is neither an aggregate ([[dcl.init.aggr]]) nor a literal type (
|
| 84 |
+
[[basic.types]]). The closure type is declared in the smallest block
|
| 85 |
+
scope, class scope, or namespace scope that contains the corresponding
|
| 86 |
+
*lambda-expression*. This determines the set of namespaces and classes
|
| 87 |
+
associated with the closure type ([[basic.lookup.argdep]]). The
|
| 88 |
+
parameter types of a *lambda-declarator* do not affect these associated
|
| 89 |
+
namespaces and classes. An implementation may define the closure type
|
| 90 |
+
differently from what is described below provided this does not alter
|
| 91 |
+
the observable behavior of the program other than by changing:
|
| 92 |
|
| 93 |
- the size and/or alignment of the closure type,
|
| 94 |
- whether the closure type is trivially copyable (Clause [[class]]),
|
| 95 |
- whether the closure type is a standard-layout class (Clause
|
| 96 |
[[class]]), or
|
|
|
|
| 98 |
|
| 99 |
An implementation shall not add members of rvalue reference type to the
|
| 100 |
closure type.
|
| 101 |
|
| 102 |
If a *lambda-expression* does not include a *lambda-declarator*, it is
|
| 103 |
+
as if the *lambda-declarator* were `()`. The lambda return type is
|
| 104 |
+
`auto`, which is replaced by the *trailing-return-type* if provided
|
| 105 |
+
and/or deduced from `return` statements as described in
|
| 106 |
+
[[dcl.spec.auto]].
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
|
| 108 |
``` cpp
|
| 109 |
auto x1 = [](int i){ return i; }; // OK: return type is int
|
| 110 |
+
auto x2 = []{ return { 1, 2 }; }; // error: deducing return type from braced-init-list
|
| 111 |
+
int j;
|
| 112 |
+
auto x3 = []()->auto&& { return j; }; // OK: return type is int&
|
| 113 |
```
|
| 114 |
|
| 115 |
+
The closure type for a non-generic *lambda-expression* has a public
|
| 116 |
+
inline function call operator ([[over.call]]) whose parameters and
|
| 117 |
+
return type are described by the *lambda-expression*’s
|
| 118 |
*parameter-declaration-clause* and *trailing-return-type* respectively.
|
| 119 |
+
For a generic lambda, the closure type has a public inline function call
|
| 120 |
+
operator member template ([[temp.mem]]) whose *template-parameter-list*
|
| 121 |
+
consists of one invented type *template-parameter* for each occurrence
|
| 122 |
+
of `auto` in the lambda’s *parameter-declaration-clause*, in order of
|
| 123 |
+
appearance. The invented type *template-parameter* is a parameter pack
|
| 124 |
+
if the corresponding *parameter-declaration* declares a function
|
| 125 |
+
parameter pack ([[dcl.fct]]). The return type and function parameters
|
| 126 |
+
of the function call operator template are derived from the
|
| 127 |
+
*lambda-expression*'s *trailing-return-type* and
|
| 128 |
+
*parameter-declaration-clause* by replacing each occurrence of `auto` in
|
| 129 |
+
the *decl-specifier*s of the *parameter-declaration-clause* with the
|
| 130 |
+
name of the corresponding invented *template-parameter*.
|
| 131 |
+
|
| 132 |
+
``` cpp
|
| 133 |
+
auto glambda = [](auto a, auto&& b) { return a < b; };
|
| 134 |
+
bool b = glambda(3, 3.14); // OK
|
| 135 |
+
auto vglambda = [](auto printer) {
|
| 136 |
+
return [=](auto&& ... ts) { // OK: ts is a function parameter pack
|
| 137 |
+
printer(std::forward<decltype(ts)>(ts)...);
|
| 138 |
+
|
| 139 |
+
return [=]() {
|
| 140 |
+
printer(ts ...);
|
| 141 |
+
};
|
| 142 |
+
};
|
| 143 |
+
};
|
| 144 |
+
auto p = vglambda( [](auto v1, auto v2, auto v3)
|
| 145 |
+
{ std::cout << v1 << v2 << v3; } );
|
| 146 |
+
auto q = p(1, 'a', 3.14); // OK: outputs 1a3.14
|
| 147 |
+
q(); // OK: outputs 1a3.14
|
| 148 |
+
```
|
| 149 |
+
|
| 150 |
+
This function call operator or operator template is declared `const` (
|
| 151 |
[[class.mfct.non-static]]) if and only if the *lambda-expression*’s
|
| 152 |
*parameter-declaration-clause* is not followed by `mutable`. It is
|
| 153 |
+
neither virtual nor declared `volatile`. Any *exception-specification*
|
| 154 |
+
specified on a *lambda-expression* applies to the corresponding function
|
| 155 |
+
call operator or operator template. An *attribute-specifier-seq* in a
|
| 156 |
+
*lambda-declarator* appertains to the type of the corresponding function
|
| 157 |
+
call operator or operator template. Names referenced in the
|
| 158 |
+
*lambda-declarator* are looked up in the context in which the
|
| 159 |
+
*lambda-expression* appears.
|
| 160 |
+
|
| 161 |
+
The closure type for a non-generic *lambda-expression* with no
|
| 162 |
+
*lambda-capture* has a public non-virtual non-explicit const conversion
|
| 163 |
+
function to pointer to function with C++language linkage ([[dcl.link]])
|
| 164 |
+
having the same parameter and return types as the closure type’s
|
| 165 |
+
function call operator. The value returned by this conversion function
|
| 166 |
+
shall be the address of a function that, when invoked, has the same
|
| 167 |
+
effect as invoking the closure type’s function call operator. For a
|
| 168 |
+
generic lambda with no *lambda-capture*, the closure type has a public
|
| 169 |
+
non-virtual non-explicit const conversion function template to pointer
|
| 170 |
+
to function. The conversion function template has the same invented
|
| 171 |
+
*template-parameter-list*, and the pointer to function has the same
|
| 172 |
+
parameter types, as the function call operator template. The return type
|
| 173 |
+
of the pointer to function shall behave as if it were a
|
| 174 |
+
*decltype-specifier* denoting the return type of the corresponding
|
| 175 |
+
function call operator template specialization. If the generic lambda
|
| 176 |
+
has no *trailing-return-type* or the *trailing-return-type* contains a
|
| 177 |
+
placeholder type, return type deduction of the corresponding function
|
| 178 |
+
call operator template specialization has to be done. The corresponding
|
| 179 |
+
specialization is that instantiation of the function call operator
|
| 180 |
+
template with the same template arguments as those deduced for the
|
| 181 |
+
conversion function template. Consider the following:
|
| 182 |
+
|
| 183 |
+
``` cpp
|
| 184 |
+
auto glambda = [](auto a) { return a; };
|
| 185 |
+
int (*fp)(int) = glambda;
|
| 186 |
+
```
|
| 187 |
+
|
| 188 |
+
The behavior of the conversion function of `glambda` above is like that
|
| 189 |
+
of the following conversion function:
|
| 190 |
+
|
| 191 |
+
``` cpp
|
| 192 |
+
struct Closure {
|
| 193 |
+
template<class T> auto operator()(T t) const { ... }
|
| 194 |
+
template<class T> static auto lambda_call_operator_invoker(T a) {
|
| 195 |
+
// forwards execution to operator()(a) and therefore has
|
| 196 |
+
// the same return type deduced
|
| 197 |
+
...
|
| 198 |
+
}
|
| 199 |
+
template<class T> using fptr_t =
|
| 200 |
+
decltype(lambda_call_operator_invoker(declval<T>())) (*)(T);
|
| 201 |
+
|
| 202 |
+
template<class T> operator fptr_t<T>() const
|
| 203 |
+
{ return &lambda_call_operator_invoker; }
|
| 204 |
+
};
|
| 205 |
+
```
|
| 206 |
+
|
| 207 |
+
``` cpp
|
| 208 |
+
void f1(int (*)(int)) { }
|
| 209 |
+
void f2(char (*)(int)) { }
|
| 210 |
+
|
| 211 |
+
void g(int (*)(int)) { } // #1
|
| 212 |
+
void g(char (*)(char)) { } // #2
|
| 213 |
+
|
| 214 |
+
void h(int (*)(int)) { } // #3
|
| 215 |
+
void h(char (*)(int)) { } // #4
|
| 216 |
+
|
| 217 |
+
auto glambda = [](auto a) { return a; };
|
| 218 |
+
f1(glambda); // OK
|
| 219 |
+
f2(glambda); // error: ID is not convertible
|
| 220 |
+
g(glambda); // error: ambiguous
|
| 221 |
+
h(glambda); // OK: calls #3 since it is convertible from ID
|
| 222 |
+
int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
|
| 223 |
+
```
|
| 224 |
+
|
| 225 |
+
The value returned by any given specialization of this conversion
|
| 226 |
+
function template shall be the address of a function that, when invoked,
|
| 227 |
+
has the same effect as invoking the generic lambda’s corresponding
|
| 228 |
+
function call operator template specialization. This will result in the
|
| 229 |
+
implicit instantiation of the generic lambda’s body. The instantiated
|
| 230 |
+
generic lambda’s return type and parameter types shall match the return
|
| 231 |
+
type and parameter types of the pointer to function.
|
| 232 |
+
|
| 233 |
+
``` cpp
|
| 234 |
+
auto GL = [](auto a) { std::cout << a; return a; };
|
| 235 |
+
int (*GL_int)(int) = GL; // OK: through conversion function template
|
| 236 |
+
GL_int(3); // OK: same as GL(3)
|
| 237 |
+
```
|
| 238 |
|
| 239 |
The *lambda-expression*’s *compound-statement* yields the
|
| 240 |
*function-body* ([[dcl.fct.def]]) of the function call operator, but
|
| 241 |
for purposes of name lookup ([[basic.lookup]]), determining the type
|
| 242 |
and value of `this` ([[class.this]]) and transforming *id-expression*s
|
|
|
|
| 256 |
};
|
| 257 |
}
|
| 258 |
};
|
| 259 |
```
|
| 260 |
|
| 261 |
+
Further, a variable `__func__` is implicitly defined at the beginning of
|
| 262 |
+
the *compound-statement* of the *lambda-expression*, with semantics as
|
| 263 |
+
described in [[dcl.fct.def.general]].
|
| 264 |
+
|
| 265 |
+
If a *lambda-capture* includes a *capture-default* that is `&`, no
|
| 266 |
+
identifier in a *simple-capture* of that *lambda-capture* shall be
|
| 267 |
+
preceded by `&`. If a *lambda-capture* includes a *capture-default* that
|
| 268 |
+
is `=`, each *simple-capture* of that *lambda-capture* shall be of the
|
| 269 |
+
form “`&` *identifier*”. Ignoring appearances in *initializer*s of
|
| 270 |
+
*init-capture*s, an identifier or `this` shall not appear more than once
|
| 271 |
+
in a *lambda-capture*.
|
| 272 |
|
| 273 |
``` cpp
|
| 274 |
struct S2 { void f(int i); };
|
| 275 |
void S2::f(int i) {
|
| 276 |
[&, i]{ }; // OK
|
|
|
|
| 279 |
[i, i]{ }; // error: i repeated
|
| 280 |
}
|
| 281 |
```
|
| 282 |
|
| 283 |
A *lambda-expression* whose smallest enclosing scope is a block scope (
|
| 284 |
+
[[basic.scope.block]]) is a *local lambda expression*; any other
|
| 285 |
+
*lambda-expression* shall not have a *capture-default* or
|
| 286 |
+
*simple-capture* in its *lambda-introducer*. The *reaching scope* of a
|
| 287 |
+
local lambda expression is the set of enclosing scopes up to and
|
| 288 |
+
including the innermost enclosing function and its parameters. This
|
| 289 |
+
reaching scope includes any intervening *lambda-expression*s.
|
| 290 |
|
| 291 |
+
The *identifier* in a *simple-capture* is looked up using the usual
|
| 292 |
rules for unqualified name lookup ([[basic.lookup.unqual]]); each such
|
| 293 |
+
lookup shall find an entity. An entity that is designated by a
|
| 294 |
+
*simple-capture* is said to be *explicitly captured*, and shall be
|
| 295 |
+
`this` or a variable with automatic storage duration declared in the
|
| 296 |
+
reaching scope of the local lambda expression.
|
| 297 |
+
|
| 298 |
+
An *init-capture* behaves as if it declares and explicitly captures a
|
| 299 |
+
variable of the form “`auto` *init-capture* `;`” whose declarative
|
| 300 |
+
region is the *lambda-expression*’s *compound-statement*, except that:
|
| 301 |
+
|
| 302 |
+
- if the capture is by copy (see below), the non-static data member
|
| 303 |
+
declared for the capture and the variable are treated as two different
|
| 304 |
+
ways of referring to the same object, which has the lifetime of the
|
| 305 |
+
non-static data member, and no additional copy and destruction is
|
| 306 |
+
performed, and
|
| 307 |
+
- if the capture is by reference, the variable’s lifetime ends when the
|
| 308 |
+
closure object’s lifetime ends.
|
| 309 |
+
|
| 310 |
+
This enables an *init-capture* like “`x = std::move(x)`”; the second
|
| 311 |
+
“`x`” must bind to a declaration in the surrounding context.
|
| 312 |
+
|
| 313 |
+
``` cpp
|
| 314 |
+
int x = 4;
|
| 315 |
+
auto y = [&r = x, x = x+1]()->int {
|
| 316 |
+
r += 2;
|
| 317 |
+
return x+2;
|
| 318 |
+
}(); // Updates ::x to 6, and initializes y to 7.
|
| 319 |
+
```
|
| 320 |
+
|
| 321 |
+
A *lambda-expression* with an associated *capture-default* that does not
|
| 322 |
+
explicitly capture `this` or a variable with automatic storage duration
|
| 323 |
+
(this excludes any *id-expression* that has been found to refer to an
|
| 324 |
+
*init-capture*'s associated non-static data member), is said to
|
| 325 |
+
*implicitly capture* the entity (i.e., `this` or a variable) if the
|
| 326 |
+
*compound-statement*:
|
| 327 |
+
|
| 328 |
+
- odr-uses ([[basic.def.odr]]) the entity, or
|
| 329 |
+
- names the entity in a potentially-evaluated expression (
|
| 330 |
+
[[basic.def.odr]]) where the enclosing full-expression depends on a
|
| 331 |
+
generic lambda parameter declared within the reaching scope of the
|
| 332 |
+
*lambda-expression*.
|
| 333 |
+
|
| 334 |
+
``` cpp
|
| 335 |
+
void f(int, const int (&)[2] = {}) { } // #1
|
| 336 |
+
void f(const int&, const int (&)[1]) { } // #2
|
| 337 |
+
void test() {
|
| 338 |
+
const int x = 17;
|
| 339 |
+
auto g = [](auto a) {
|
| 340 |
+
f(x); // OK: calls #1, does not capture x
|
| 341 |
+
};
|
| 342 |
+
|
| 343 |
+
auto g2 = [=](auto a) {
|
| 344 |
+
int selector[sizeof(a) == 1 ? 1 : 2]{};
|
| 345 |
+
f(x, selector); // OK: is a dependent expression, so captures x
|
| 346 |
+
};
|
| 347 |
+
}
|
| 348 |
+
```
|
| 349 |
+
|
| 350 |
+
All such implicitly captured entities shall be declared within the
|
| 351 |
+
reaching scope of the lambda expression. The implicit capture of an
|
| 352 |
+
entity by a nested *lambda-expression* can cause its implicit capture by
|
| 353 |
+
the containing *lambda-expression* (see below). Implicit odr-uses of
|
| 354 |
+
`this` can result in implicit capture.
|
| 355 |
|
| 356 |
An entity is *captured* if it is captured explicitly or implicitly. An
|
| 357 |
entity captured by a *lambda-expression* is odr-used (
|
| 358 |
[[basic.def.odr]]) in the scope containing the *lambda-expression*. If
|
| 359 |
`this` is captured by a local lambda expression, its nearest enclosing
|
| 360 |
function shall be a non-static member function. If a *lambda-expression*
|
| 361 |
+
or an instantiation of the function call operator template of a generic
|
| 362 |
+
lambda odr-uses ([[basic.def.odr]]) `this` or a variable with automatic
|
| 363 |
storage duration from its reaching scope, that entity shall be captured
|
| 364 |
by the *lambda-expression*. If a *lambda-expression* captures an entity
|
| 365 |
and that entity is not defined or captured in the immediately enclosing
|
| 366 |
lambda expression or function, the program is ill-formed.
|
| 367 |
|
|
|
|
| 411 |
}
|
| 412 |
```
|
| 413 |
|
| 414 |
An entity is *captured by copy* if it is implicitly captured and the
|
| 415 |
*capture-default* is `=` or if it is explicitly captured with a capture
|
| 416 |
+
that is not of the form `&` *identifier* or `&` *identifier*
|
| 417 |
+
*initializer*. For each entity captured by copy, an unnamed non-static
|
| 418 |
+
data member is declared in the closure type. The declaration order of
|
| 419 |
+
these members is unspecified. The type of such a data member is the type
|
| 420 |
+
of the corresponding captured entity if the entity is not a reference to
|
| 421 |
+
an object, or the referenced type otherwise. If the captured entity is a
|
| 422 |
+
reference to a function, the corresponding data member is also a
|
| 423 |
+
reference to a function. A member of an anonymous union shall not be
|
| 424 |
+
captured by copy.
|
| 425 |
|
| 426 |
An entity is *captured by reference* if it is implicitly or explicitly
|
| 427 |
captured but not captured by copy. It is unspecified whether additional
|
| 428 |
unnamed non-static data members are declared in the closure type for
|
| 429 |
+
entities captured by reference. A member of an anonymous union shall not
|
| 430 |
+
be captured by reference.
|
| 431 |
|
| 432 |
If a *lambda-expression* `m2` captures an entity and that entity is
|
| 433 |
captured by an immediately enclosing *lambda-expression* `m1`, then
|
| 434 |
`m2`’s capture is transformed as follows:
|
| 435 |
|
|
|
|
| 454 |
a = 2; b = 2; c = 2;
|
| 455 |
m1();
|
| 456 |
std::cout << a << b << c;
|
| 457 |
```
|
| 458 |
|
| 459 |
+
Every *id-expression* within the *compound-statement* of a
|
| 460 |
+
*lambda-expression* that is an odr-use ([[basic.def.odr]]) of an entity
|
| 461 |
+
captured by copy is transformed into an access to the corresponding
|
| 462 |
+
unnamed data member of the closure type. An *id-expression* that is not
|
| 463 |
+
an odr-use refers to the original entity, never to a member of the
|
| 464 |
+
closure type. Furthermore, such an *id-expression* does not cause the
|
| 465 |
+
implicit capture of the entity. If `this` is captured, each odr-use of
|
| 466 |
+
`this` is transformed into an access to the corresponding unnamed data
|
| 467 |
+
member of the closure type, cast ([[expr.cast]]) to the type of `this`.
|
| 468 |
+
The cast ensures that the transformed expression is a prvalue.
|
| 469 |
|
| 470 |
``` cpp
|
| 471 |
void f(const int*);
|
| 472 |
void g() {
|
| 473 |
const int N = 10;
|
| 474 |
[=] {
|
| 475 |
int arr[N]; // OK: not an odr-use, refers to automatic variable
|
| 476 |
f(&N); // OK: causes N to be captured; &N points to the
|
| 477 |
// corresponding member of the closure type
|
| 478 |
+
};
|
| 479 |
}
|
| 480 |
```
|
| 481 |
|
| 482 |
Every occurrence of `decltype((x))` where `x` is a possibly
|
| 483 |
parenthesized *id-expression* that names an entity of automatic storage
|
|
|
|
| 509 |
The closure type associated with a *lambda-expression* has an
|
| 510 |
implicitly-declared destructor ([[class.dtor]]).
|
| 511 |
|
| 512 |
When the *lambda-expression* is evaluated, the entities that are
|
| 513 |
captured by copy are used to direct-initialize each corresponding
|
| 514 |
+
non-static data member of the resulting closure object, and the
|
| 515 |
+
non-static data members corresponding to the *init-capture*s are
|
| 516 |
+
initialized as indicated by the corresponding *initializer* (which may
|
| 517 |
+
be copy- or direct-initialization). (For array members, the array
|
| 518 |
+
elements are direct-initialized in increasing subscript order.) These
|
| 519 |
+
initializations are performed in the (unspecified) order in which the
|
| 520 |
+
non-static data members are declared. This ensures that the destructions
|
| 521 |
+
will occur in the reverse order of the constructions.
|
| 522 |
|
| 523 |
If an entity is implicitly or explicitly captured by reference, invoking
|
| 524 |
the function call operator of the corresponding *lambda-expression*
|
| 525 |
after the lifetime of the entity has ended is likely to result in
|
| 526 |
undefined behavior.
|
| 527 |
|
| 528 |
+
A *simple-capture* followed by an ellipsis is a pack expansion (
|
| 529 |
+
[[temp.variadic]]). An *init-capture* followed by an ellipsis is
|
| 530 |
+
ill-formed.
|
| 531 |
|
| 532 |
``` cpp
|
| 533 |
template<class... Args>
|
| 534 |
void f(Args... args) {
|
| 535 |
auto lm = [&, args...] { return g(args...); };
|