- tmp/tmpm825b934/{from.md → to.md} +278 -214
tmp/tmpm825b934/{from.md → to.md}
RENAMED
|
@@ -1,25 +1,26 @@
|
|
| 1 |
### Lambda expressions <a id="expr.prim.lambda">[[expr.prim.lambda]]</a>
|
| 2 |
|
| 3 |
``` bnf
|
| 4 |
lambda-expression:
|
| 5 |
lambda-introducer lambda-declaratorₒₚₜ compound-statement
|
|
|
|
| 6 |
```
|
| 7 |
|
| 8 |
``` bnf
|
| 9 |
lambda-introducer:
|
| 10 |
'[' lambda-captureₒₚₜ ']'
|
| 11 |
```
|
| 12 |
|
| 13 |
``` bnf
|
| 14 |
lambda-declarator:
|
| 15 |
'(' parameter-declaration-clause ')' decl-specifier-seqₒₚₜ
|
| 16 |
-
noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ trailing-return-typeₒₚₜ
|
| 17 |
```
|
| 18 |
|
| 19 |
-
|
| 20 |
-
|
| 21 |
|
| 22 |
[*Example 1*:
|
| 23 |
|
| 24 |
``` cpp
|
| 25 |
#include <algorithm>
|
|
@@ -30,24 +31,20 @@ void abssort(float* x, unsigned N) {
|
|
| 30 |
```
|
| 31 |
|
| 32 |
— *end example*]
|
| 33 |
|
| 34 |
A *lambda-expression* is a prvalue whose result object is called the
|
| 35 |
-
*closure object*.
|
| 36 |
-
unevaluated operand (Clause [[expr]]), in a *template-argument*, in an
|
| 37 |
-
*alias-declaration*, in a typedef declaration, or in the declaration of
|
| 38 |
-
a function or function template outside its function body and default
|
| 39 |
-
arguments.
|
| 40 |
|
| 41 |
-
[*Note 1*:
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
[*Note 2*: A closure object behaves like a function object (
|
| 45 |
-
[[function.objects]]). — *end note*]
|
| 46 |
|
| 47 |
In the *decl-specifier-seq* of the *lambda-declarator*, each
|
| 48 |
-
*decl-specifier* shall
|
|
|
|
|
|
|
|
|
|
| 49 |
|
| 50 |
If a *lambda-expression* does not include a *lambda-declarator*, it is
|
| 51 |
as if the *lambda-declarator* were `()`. The lambda return type is
|
| 52 |
`auto`, which is replaced by the type specified by the
|
| 53 |
*trailing-return-type* if provided and/or deduced from `return`
|
|
@@ -62,54 +59,63 @@ int j;
|
|
| 62 |
auto x3 = []()->auto&& { return j; }; // OK: return type is int&
|
| 63 |
```
|
| 64 |
|
| 65 |
— *end example*]
|
| 66 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
#### Closure types <a id="expr.prim.lambda.closure">[[expr.prim.lambda.closure]]</a>
|
| 68 |
|
| 69 |
The type of a *lambda-expression* (which is also the type of the closure
|
| 70 |
object) is a unique, unnamed non-union class type, called the *closure
|
| 71 |
type*, whose properties are described below.
|
| 72 |
|
| 73 |
The closure type is declared in the smallest block scope, class scope,
|
| 74 |
or namespace scope that contains the corresponding *lambda-expression*.
|
| 75 |
|
| 76 |
[*Note 1*: This determines the set of namespaces and classes associated
|
| 77 |
-
with the closure type
|
| 78 |
-
|
| 79 |
classes. — *end note*]
|
| 80 |
|
| 81 |
-
The closure type is not an aggregate type
|
| 82 |
implementation may define the closure type differently from what is
|
| 83 |
described below provided this does not alter the observable behavior of
|
| 84 |
the program other than by changing:
|
| 85 |
|
| 86 |
- the size and/or alignment of the closure type,
|
| 87 |
-
- whether the closure type is trivially copyable
|
| 88 |
-
- whether the closure type is a standard-layout class
|
| 89 |
-
[[class]]), or
|
| 90 |
-
- whether the closure type is a POD class (Clause [[class]]).
|
| 91 |
|
| 92 |
An implementation shall not add members of rvalue reference type to the
|
| 93 |
closure type.
|
| 94 |
|
| 95 |
-
The closure type for a
|
| 96 |
-
|
|
|
|
| 97 |
return type are described by the *lambda-expression*’s
|
| 98 |
-
*parameter-declaration-clause* and *trailing-return-type* respectively
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
*parameter-declaration-clause* by replacing each occurrence of `auto` in
|
| 109 |
-
the *decl-specifier*s of the *parameter-declaration-clause* with the
|
| 110 |
-
name of the corresponding invented *template-parameter*.
|
| 111 |
|
| 112 |
[*Example 1*:
|
| 113 |
|
| 114 |
``` cpp
|
| 115 |
auto glambda = [](auto a, auto&& b) { return a < b; };
|
|
@@ -140,14 +146,17 @@ specified on a *lambda-expression* applies to the corresponding function
|
|
| 140 |
call operator or operator template. An *attribute-specifier-seq* in a
|
| 141 |
*lambda-declarator* appertains to the type of the corresponding function
|
| 142 |
call operator or operator template. The function call operator or any
|
| 143 |
given operator template specialization is a constexpr function if either
|
| 144 |
the corresponding *lambda-expression*'s *parameter-declaration-clause*
|
| 145 |
-
is followed by `constexpr`, or it satisfies the
|
| 146 |
-
constexpr function
|
|
|
|
|
|
|
|
|
|
| 147 |
|
| 148 |
-
[*Note
|
| 149 |
the context in which the *lambda-expression* appears. — *end note*]
|
| 150 |
|
| 151 |
[*Example 2*:
|
| 152 |
|
| 153 |
``` cpp
|
|
@@ -156,11 +165,11 @@ static_assert(ID(3) == 3); // OK
|
|
| 156 |
|
| 157 |
struct NonLiteral {
|
| 158 |
NonLiteral(int n) : n(n) { }
|
| 159 |
int n;
|
| 160 |
};
|
| 161 |
-
static_assert(ID(NonLiteral{3}).n == 3);
|
| 162 |
```
|
| 163 |
|
| 164 |
— *end example*]
|
| 165 |
|
| 166 |
[*Example 3*:
|
|
@@ -184,35 +193,65 @@ static_assert(add(one)(zero)() == one()); // OK
|
|
| 184 |
// Since two below is not declared constexpr, an evaluation of its constexpr member function call operator
|
| 185 |
// cannot perform an lvalue-to-rvalue conversion on one of its subobjects (that represents its capture)
|
| 186 |
// in a constant expression.
|
| 187 |
auto two = monoid(2);
|
| 188 |
assert(two() == 2); // OK, not a constant expression.
|
| 189 |
-
static_assert(add(one)(one)() == two());
|
| 190 |
static_assert(add(one)(one)() == monoid(2)()); // OK
|
| 191 |
```
|
| 192 |
|
| 193 |
— *end example*]
|
| 194 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
The closure type for a non-generic *lambda-expression* with no
|
| 196 |
-
*lambda-capture*
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
parameter types, as the function call operator template. The return type
|
| 209 |
-
of the pointer to function shall behave as if it were a
|
| 210 |
-
*decltype-specifier* denoting the return type of the corresponding
|
| 211 |
-
function call operator template specialization.
|
| 212 |
|
| 213 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
|
| 215 |
If the generic lambda has no *trailing-return-type* or the
|
| 216 |
*trailing-return-type* contains a placeholder type, return type
|
| 217 |
deduction of the corresponding function call operator template
|
| 218 |
specialization has to be done. The corresponding specialization is that
|
|
@@ -244,11 +283,11 @@ struct Closure {
|
|
| 244 |
};
|
| 245 |
```
|
| 246 |
|
| 247 |
— *end note*]
|
| 248 |
|
| 249 |
-
[*Example
|
| 250 |
|
| 251 |
``` cpp
|
| 252 |
void f1(int (*)(int)) { }
|
| 253 |
void f2(char (*)(int)) { }
|
| 254 |
|
|
@@ -269,19 +308,22 @@ int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
|
|
| 269 |
— *end example*]
|
| 270 |
|
| 271 |
The value returned by any given specialization of this conversion
|
| 272 |
function template is the address of a function `F` that, when invoked,
|
| 273 |
has the same effect as invoking the generic lambda’s corresponding
|
| 274 |
-
function call operator template specialization
|
| 275 |
-
|
|
|
|
|
|
|
|
|
|
| 276 |
|
| 277 |
-
[*Note
|
| 278 |
generic lambda’s body. The instantiated generic lambda’s return type and
|
| 279 |
-
parameter types
|
| 280 |
-
pointer to function. — *end note*]
|
| 281 |
|
| 282 |
-
[*Example
|
| 283 |
|
| 284 |
``` cpp
|
| 285 |
auto GL = [](auto a) { std::cout << a; return a; };
|
| 286 |
int (*GL_int)(int) = GL; // OK: through conversion function template
|
| 287 |
GL_int(3); // OK: same as GL(3)
|
|
@@ -289,37 +331,36 @@ GL_int(3); // OK: same as GL(3)
|
|
| 289 |
|
| 290 |
— *end example*]
|
| 291 |
|
| 292 |
The conversion function or conversion function template is public,
|
| 293 |
constexpr, non-virtual, non-explicit, const, and has a non-throwing
|
| 294 |
-
exception specification
|
| 295 |
|
| 296 |
-
[*Example
|
| 297 |
|
| 298 |
``` cpp
|
| 299 |
auto Fwd = [](int (*fp)(int), auto a) { return fp(a); };
|
| 300 |
auto C = [](auto a) { return a; };
|
| 301 |
|
| 302 |
static_assert(Fwd(C,3) == 3); // OK
|
| 303 |
|
| 304 |
// No specialization of the function call operator template can be constexpr (due to the local static).
|
| 305 |
auto NC = [](auto a) { static int s; return a; };
|
| 306 |
-
static_assert(Fwd(NC,3) == 3);
|
| 307 |
```
|
| 308 |
|
| 309 |
— *end example*]
|
| 310 |
|
| 311 |
The *lambda-expression*’s *compound-statement* yields the
|
| 312 |
-
*function-body*
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
*lambda-expression*.
|
| 319 |
|
| 320 |
-
[*Example
|
| 321 |
|
| 322 |
``` cpp
|
| 323 |
struct S1 {
|
| 324 |
int x, y;
|
| 325 |
int operator()(int);
|
|
@@ -337,22 +378,26 @@ struct S1 {
|
|
| 337 |
Further, a variable `__func__` is implicitly defined at the beginning of
|
| 338 |
the *compound-statement* of the *lambda-expression*, with semantics as
|
| 339 |
described in [[dcl.fct.def.general]].
|
| 340 |
|
| 341 |
The closure type associated with a *lambda-expression* has no default
|
| 342 |
-
constructor
|
| 343 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 344 |
|
| 345 |
-
[*Note
|
| 346 |
usual, and might therefore be defined as deleted. — *end note*]
|
| 347 |
|
| 348 |
The closure type associated with a *lambda-expression* has an
|
| 349 |
-
implicitly-declared destructor
|
| 350 |
|
| 351 |
-
A member of a closure type shall not be explicitly instantiated
|
| 352 |
-
[[temp.explicit]]
|
| 353 |
-
|
| 354 |
|
| 355 |
#### Captures <a id="expr.prim.lambda.capture">[[expr.prim.lambda.capture]]</a>
|
| 356 |
|
| 357 |
``` bnf
|
| 358 |
lambda-capture:
|
|
@@ -367,43 +412,43 @@ capture-default:
|
|
| 367 |
'='
|
| 368 |
```
|
| 369 |
|
| 370 |
``` bnf
|
| 371 |
capture-list:
|
| 372 |
-
capture
|
| 373 |
-
capture-list ',' capture
|
| 374 |
```
|
| 375 |
|
| 376 |
``` bnf
|
| 377 |
capture:
|
| 378 |
simple-capture
|
| 379 |
init-capture
|
| 380 |
```
|
| 381 |
|
| 382 |
``` bnf
|
| 383 |
simple-capture:
|
| 384 |
-
identifier
|
| 385 |
-
'&' identifier
|
| 386 |
-
|
| 387 |
-
'* this'
|
| 388 |
```
|
| 389 |
|
| 390 |
``` bnf
|
| 391 |
init-capture:
|
| 392 |
-
identifier initializer
|
| 393 |
-
'&' identifier initializer
|
| 394 |
```
|
| 395 |
|
| 396 |
The body of a *lambda-expression* may refer to variables with automatic
|
| 397 |
storage duration and the `*this` object (if any) of enclosing block
|
| 398 |
scopes by capturing those entities, as described below.
|
| 399 |
|
| 400 |
If a *lambda-capture* includes a *capture-default* that is `&`, no
|
| 401 |
identifier in a *simple-capture* of that *lambda-capture* shall be
|
| 402 |
preceded by `&`. If a *lambda-capture* includes a *capture-default* that
|
| 403 |
is `=`, each *simple-capture* of that *lambda-capture* shall be of the
|
| 404 |
-
form “`&` *identifier*” or “`* this`”.
|
| 405 |
|
| 406 |
[*Note 1*: The form `[&,this]` is redundant but accepted for
|
| 407 |
compatibility with ISO C++14. — *end note*]
|
| 408 |
|
| 409 |
Ignoring appearances in *initializer*s of *init-capture*s, an identifier
|
|
@@ -413,66 +458,62 @@ or `this` shall not appear more than once in a *lambda-capture*.
|
|
| 413 |
|
| 414 |
``` cpp
|
| 415 |
struct S2 { void f(int i); };
|
| 416 |
void S2::f(int i) {
|
| 417 |
[&, i]{ }; // OK
|
|
|
|
| 418 |
[&, &i]{ }; // error: i preceded by & when & is the default
|
| 419 |
[=, *this]{ }; // OK
|
| 420 |
-
[=, this]{ }; //
|
| 421 |
[i, i]{ }; // error: i repeated
|
| 422 |
[this, *this]{ }; // error: this appears twice
|
| 423 |
}
|
| 424 |
```
|
| 425 |
|
| 426 |
— *end example*]
|
| 427 |
|
| 428 |
-
A *lambda-expression*
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
including the innermost enclosing function and its parameters.
|
| 434 |
-
|
| 435 |
-
[*Note 2*: This reaching scope includes any intervening
|
| 436 |
-
*lambda-expression*s. — *end note*]
|
| 437 |
|
| 438 |
The *identifier* in a *simple-capture* is looked up using the usual
|
| 439 |
-
rules for unqualified name lookup
|
| 440 |
-
lookup shall find
|
| 441 |
-
*
|
| 442 |
-
|
| 443 |
-
variable with automatic storage duration declared in the reaching scope
|
| 444 |
-
of the local lambda expression.
|
| 445 |
|
| 446 |
If an *identifier* in a *simple-capture* appears as the *declarator-id*
|
| 447 |
of a parameter of the *lambda-declarator*'s
|
| 448 |
*parameter-declaration-clause*, the program is ill-formed.
|
| 449 |
|
| 450 |
[*Example 2*:
|
| 451 |
|
| 452 |
``` cpp
|
| 453 |
void f() {
|
| 454 |
int x = 0;
|
| 455 |
-
auto g = [x](int x) { return 0; } // error: parameter and simple-capture have the same name
|
| 456 |
}
|
| 457 |
```
|
| 458 |
|
| 459 |
— *end example*]
|
| 460 |
|
| 461 |
-
An *init-capture* behaves as if it declares and
|
| 462 |
-
variable of the form “`auto` *init-capture* `;`”
|
| 463 |
-
region is the *lambda-expression*’s
|
|
|
|
| 464 |
|
| 465 |
- if the capture is by copy (see below), the non-static data member
|
| 466 |
declared for the capture and the variable are treated as two different
|
| 467 |
ways of referring to the same object, which has the lifetime of the
|
| 468 |
non-static data member, and no additional copy and destruction is
|
| 469 |
performed, and
|
| 470 |
- if the capture is by reference, the variable’s lifetime ends when the
|
| 471 |
closure object’s lifetime ends.
|
| 472 |
|
| 473 |
-
[*Note
|
| 474 |
the second “`x`” must bind to a declaration in the surrounding
|
| 475 |
context. — *end note*]
|
| 476 |
|
| 477 |
[*Example 3*:
|
| 478 |
|
|
@@ -481,71 +522,100 @@ int x = 4;
|
|
| 481 |
auto y = [&r = x, x = x+1]()->int {
|
| 482 |
r += 2;
|
| 483 |
return x+2;
|
| 484 |
}(); // Updates ::x to 6, and initializes y to 7.
|
| 485 |
|
| 486 |
-
auto z = [a = 42](int a) { return 1; }
|
| 487 |
```
|
| 488 |
|
| 489 |
— *end example*]
|
| 490 |
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
(this excludes any *id-expression* that has been found to refer to an
|
| 494 |
-
*init-capture*'s associated non-static data member), is said to
|
| 495 |
-
*implicitly capture* the entity (i.e., `*this` or a variable) if the
|
| 496 |
-
*compound-statement*:
|
| 497 |
|
| 498 |
-
-
|
| 499 |
-
|
| 500 |
-
|
| 501 |
-
|
| 502 |
-
|
| 503 |
-
|
| 504 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 505 |
|
| 506 |
[*Example 4*:
|
| 507 |
|
| 508 |
``` cpp
|
| 509 |
-
void f(int, const int (&)[2] = {})
|
| 510 |
-
void f(const int&, const int (&)[1])
|
| 511 |
void test() {
|
| 512 |
const int x = 17;
|
| 513 |
auto g = [](auto a) {
|
| 514 |
f(x); // OK: calls #1, does not capture x
|
| 515 |
};
|
| 516 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 517 |
auto g2 = [=](auto a) {
|
| 518 |
int selector[sizeof(a) == 1 ? 1 : 2]{};
|
| 519 |
-
f(x, selector); // OK:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 520 |
};
|
| 521 |
}
|
| 522 |
```
|
| 523 |
|
|
|
|
|
|
|
|
|
|
| 524 |
— *end example*]
|
| 525 |
|
| 526 |
-
|
| 527 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 528 |
|
| 529 |
-
|
| 530 |
-
*lambda-expression* can cause its implicit capture by the containing
|
| 531 |
-
*lambda-expression* (see below). Implicit odr-uses of `this` can result
|
| 532 |
-
in implicit capture. — *end note*]
|
| 533 |
|
| 534 |
An entity is *captured* if it is captured explicitly or implicitly. An
|
| 535 |
-
entity captured by a *lambda-expression* is odr-used
|
| 536 |
-
|
| 537 |
-
`*this` is captured by a local lambda expression, its nearest enclosing
|
| 538 |
-
function shall be a non-static member function. If a *lambda-expression*
|
| 539 |
-
or an instantiation of the function call operator template of a generic
|
| 540 |
-
lambda odr-uses ([[basic.def.odr]]) `this` or a variable with automatic
|
| 541 |
-
storage duration from its reaching scope, that entity shall be captured
|
| 542 |
-
by the *lambda-expression*. If a *lambda-expression* captures an entity
|
| 543 |
-
and that entity is not defined or captured in the immediately enclosing
|
| 544 |
-
lambda expression or function, the program is ill-formed.
|
| 545 |
|
| 546 |
-
[*
|
|
|
|
|
|
|
|
|
|
|
|
|
| 547 |
|
| 548 |
``` cpp
|
| 549 |
void f1(int i) {
|
| 550 |
int const N = 20;
|
| 551 |
auto m1 = [=]{
|
|
@@ -559,14 +629,15 @@ void f1(int i) {
|
|
| 559 |
int f;
|
| 560 |
void work(int n) {
|
| 561 |
int m = n*n;
|
| 562 |
int j = 40;
|
| 563 |
auto m3 = [this,m] {
|
| 564 |
-
auto m4 = [&,j] { // error: j not
|
| 565 |
-
int x = n; // error: n
|
| 566 |
x += m; // OK: m implicitly captured by m4 and explicitly captured by m3
|
| 567 |
-
x += i; // error: i is
|
|
|
|
| 568 |
x += f; // OK: this captured implicitly by m4 and explicitly by m3
|
| 569 |
};
|
| 570 |
};
|
| 571 |
}
|
| 572 |
};
|
|
@@ -576,11 +647,11 @@ struct s2 {
|
|
| 576 |
double ohseven = .007;
|
| 577 |
auto f() {
|
| 578 |
return [this] {
|
| 579 |
return [*this] {
|
| 580 |
return ohseven; // OK
|
| 581 |
-
}
|
| 582 |
}();
|
| 583 |
}
|
| 584 |
auto g() {
|
| 585 |
return [] {
|
| 586 |
return [*this] { }; // error: *this not captured by outer lambda-expression
|
|
@@ -589,23 +660,30 @@ struct s2 {
|
|
| 589 |
};
|
| 590 |
```
|
| 591 |
|
| 592 |
— *end example*]
|
| 593 |
|
| 594 |
-
|
| 595 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 596 |
|
| 597 |
-
[*Example
|
| 598 |
|
| 599 |
``` cpp
|
| 600 |
void f2() {
|
| 601 |
int i = 1;
|
| 602 |
-
void g1(int = ([i]{ return i; })()); //
|
| 603 |
-
void g2(int = ([i]{ return 0; })()); //
|
| 604 |
-
void g3(int = ([=]{ return i; })()); //
|
| 605 |
void g4(int = ([=]{ return 0; })()); // OK
|
| 606 |
void g5(int = ([]{ return sizeof i; })()); // OK
|
|
|
|
|
|
|
| 607 |
}
|
| 608 |
```
|
| 609 |
|
| 610 |
— *end example*]
|
| 611 |
|
|
@@ -623,36 +701,24 @@ the entity is a reference to an object, an lvalue reference to the
|
|
| 623 |
referenced function type if the entity is a reference to a function, or
|
| 624 |
the type of the corresponding captured entity otherwise. A member of an
|
| 625 |
anonymous union shall not be captured by copy.
|
| 626 |
|
| 627 |
Every *id-expression* within the *compound-statement* of a
|
| 628 |
-
*lambda-expression* that is an odr-use
|
| 629 |
captured by copy is transformed into an access to the corresponding
|
| 630 |
unnamed data member of the closure type.
|
| 631 |
|
| 632 |
-
[*Note
|
| 633 |
-
original entity, never to a member of the closure type.
|
| 634 |
-
|
| 635 |
entity. — *end note*]
|
| 636 |
|
| 637 |
-
If `*this` is captured by copy, each odr-
|
| 638 |
-
|
| 639 |
-
|
| 640 |
|
| 641 |
-
[*
|
| 642 |
-
prvalue. — *end note*]
|
| 643 |
-
|
| 644 |
-
An *id-expression* within the *compound-statement* of a
|
| 645 |
-
*lambda-expression* that is an odr-use of a reference captured by
|
| 646 |
-
reference refers to the entity to which the captured reference is bound
|
| 647 |
-
and not to the captured reference.
|
| 648 |
-
|
| 649 |
-
[*Note 7*: The validity of such captures is determined by the lifetime
|
| 650 |
-
of the object to which the reference refers, not by the lifetime of the
|
| 651 |
-
reference itself. — *end note*]
|
| 652 |
-
|
| 653 |
-
[*Example 7*:
|
| 654 |
|
| 655 |
``` cpp
|
| 656 |
void f(const int*);
|
| 657 |
void g() {
|
| 658 |
const int N = 10;
|
|
@@ -660,27 +726,21 @@ void g() {
|
|
| 660 |
int arr[N]; // OK: not an odr-use, refers to automatic variable
|
| 661 |
f(&N); // OK: causes N to be captured; &N points to
|
| 662 |
// the corresponding member of the closure type
|
| 663 |
};
|
| 664 |
}
|
| 665 |
-
auto h(int &r) {
|
| 666 |
-
return [&] {
|
| 667 |
-
++r; // Valid after h returns if the lifetime of the
|
| 668 |
-
// object to which r is bound has not ended
|
| 669 |
-
};
|
| 670 |
-
}
|
| 671 |
```
|
| 672 |
|
| 673 |
— *end example*]
|
| 674 |
|
| 675 |
An entity is *captured by reference* if it is implicitly or explicitly
|
| 676 |
captured but not captured by copy. It is unspecified whether additional
|
| 677 |
unnamed non-static data members are declared in the closure type for
|
| 678 |
entities captured by reference. If declared, such non-static data
|
| 679 |
members shall be of literal type.
|
| 680 |
|
| 681 |
-
[*Example
|
| 682 |
|
| 683 |
``` cpp
|
| 684 |
// The inner closure type must be a literal type regardless of how reference captures are represented.
|
| 685 |
static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4);
|
| 686 |
```
|
|
@@ -688,22 +748,44 @@ static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4);
|
|
| 688 |
— *end example*]
|
| 689 |
|
| 690 |
A bit-field or a member of an anonymous union shall not be captured by
|
| 691 |
reference.
|
| 692 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 693 |
If a *lambda-expression* `m2` captures an entity and that entity is
|
| 694 |
captured by an immediately enclosing *lambda-expression* `m1`, then
|
| 695 |
`m2`’s capture is transformed as follows:
|
| 696 |
|
| 697 |
- if `m1` captures the entity by copy, `m2` captures the corresponding
|
| 698 |
non-static data member of `m1`’s closure type;
|
| 699 |
- if `m1` captures the entity by reference, `m2` captures the same
|
| 700 |
entity captured by `m1`.
|
| 701 |
|
| 702 |
-
[*Example
|
| 703 |
|
| 704 |
-
The nested lambda
|
| 705 |
`123234`.
|
| 706 |
|
| 707 |
``` cpp
|
| 708 |
int a = 1, b = 1, c = 1;
|
| 709 |
auto m1 = [a, &b, &c]() mutable {
|
|
@@ -719,61 +801,43 @@ m1();
|
|
| 719 |
std::cout << a << b << c;
|
| 720 |
```
|
| 721 |
|
| 722 |
— *end example*]
|
| 723 |
|
| 724 |
-
Every occurrence of `decltype((x))` where `x` is a possibly
|
| 725 |
-
parenthesized *id-expression* that names an entity of automatic storage
|
| 726 |
-
duration is treated as if `x` were transformed into an access to a
|
| 727 |
-
corresponding data member of the closure type that would have been
|
| 728 |
-
declared if `x` were an odr-use of the denoted entity.
|
| 729 |
-
|
| 730 |
-
[*Example 10*:
|
| 731 |
-
|
| 732 |
-
``` cpp
|
| 733 |
-
void f3() {
|
| 734 |
-
float x, &r = x;
|
| 735 |
-
[=] { // x and r are not captured (appearance in a decltype operand is not an odr-use)
|
| 736 |
-
decltype(x) y1; // y1 has type float
|
| 737 |
-
decltype((x)) y2 = y1; // y2 has type float const& because this lambda is not mutable and x is an lvalue
|
| 738 |
-
decltype(r) r1 = y1; // r1 has type float& (transformation not considered)
|
| 739 |
-
decltype((r)) r2 = y2; // r2 has type float const&
|
| 740 |
-
};
|
| 741 |
-
}
|
| 742 |
-
```
|
| 743 |
-
|
| 744 |
-
— *end example*]
|
| 745 |
-
|
| 746 |
When the *lambda-expression* is evaluated, the entities that are
|
| 747 |
captured by copy are used to direct-initialize each corresponding
|
| 748 |
non-static data member of the resulting closure object, and the
|
| 749 |
non-static data members corresponding to the *init-capture*s are
|
| 750 |
initialized as indicated by the corresponding *initializer* (which may
|
| 751 |
be copy- or direct-initialization). (For array members, the array
|
| 752 |
elements are direct-initialized in increasing subscript order.) These
|
| 753 |
initializations are performed in the (unspecified) order in which the
|
| 754 |
non-static data members are declared.
|
| 755 |
|
| 756 |
-
[*Note
|
| 757 |
order of the constructions. — *end note*]
|
| 758 |
|
| 759 |
-
[*Note
|
| 760 |
captured by reference, invoking the function call operator of the
|
| 761 |
corresponding *lambda-expression* after the lifetime of the entity has
|
| 762 |
ended is likely to result in undefined behavior. — *end note*]
|
| 763 |
|
| 764 |
-
A *simple-capture*
|
| 765 |
-
[[temp.variadic]]
|
| 766 |
-
|
|
|
|
| 767 |
|
| 768 |
-
[*Example
|
| 769 |
|
| 770 |
``` cpp
|
| 771 |
template<class... Args>
|
| 772 |
void f(Args... args) {
|
| 773 |
auto lm = [&, args...] { return g(args...); };
|
| 774 |
lm();
|
|
|
|
|
|
|
|
|
|
| 775 |
}
|
| 776 |
```
|
| 777 |
|
| 778 |
— *end example*]
|
| 779 |
|
|
|
|
| 1 |
### Lambda expressions <a id="expr.prim.lambda">[[expr.prim.lambda]]</a>
|
| 2 |
|
| 3 |
``` bnf
|
| 4 |
lambda-expression:
|
| 5 |
lambda-introducer lambda-declaratorₒₚₜ compound-statement
|
| 6 |
+
lambda-introducer '<' template-parameter-list '>' requires-clauseₒₚₜ lambda-declaratorₒₚₜ compound-statement
|
| 7 |
```
|
| 8 |
|
| 9 |
``` bnf
|
| 10 |
lambda-introducer:
|
| 11 |
'[' lambda-captureₒₚₜ ']'
|
| 12 |
```
|
| 13 |
|
| 14 |
``` bnf
|
| 15 |
lambda-declarator:
|
| 16 |
'(' parameter-declaration-clause ')' decl-specifier-seqₒₚₜ
|
| 17 |
+
noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ trailing-return-typeₒₚₜ requires-clauseₒₚₜ
|
| 18 |
```
|
| 19 |
|
| 20 |
+
A *lambda-expression* provides a concise way to create a simple function
|
| 21 |
+
object.
|
| 22 |
|
| 23 |
[*Example 1*:
|
| 24 |
|
| 25 |
``` cpp
|
| 26 |
#include <algorithm>
|
|
|
|
| 31 |
```
|
| 32 |
|
| 33 |
— *end example*]
|
| 34 |
|
| 35 |
A *lambda-expression* is a prvalue whose result object is called the
|
| 36 |
+
*closure object*.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
|
| 38 |
+
[*Note 1*: A closure object behaves like a function object
|
| 39 |
+
[[function.objects]]. — *end note*]
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
In the *decl-specifier-seq* of the *lambda-declarator*, each
|
| 42 |
+
*decl-specifier* shall be one of `mutable`, `constexpr`, or `consteval`.
|
| 43 |
+
|
| 44 |
+
[*Note 2*: The trailing *requires-clause* is described in
|
| 45 |
+
[[dcl.decl]]. — *end note*]
|
| 46 |
|
| 47 |
If a *lambda-expression* does not include a *lambda-declarator*, it is
|
| 48 |
as if the *lambda-declarator* were `()`. The lambda return type is
|
| 49 |
`auto`, which is replaced by the type specified by the
|
| 50 |
*trailing-return-type* if provided and/or deduced from `return`
|
|
|
|
| 59 |
auto x3 = []()->auto&& { return j; }; // OK: return type is int&
|
| 60 |
```
|
| 61 |
|
| 62 |
— *end example*]
|
| 63 |
|
| 64 |
+
A lambda is a *generic lambda* if the *lambda-expression* has any
|
| 65 |
+
generic parameter type placeholders [[dcl.spec.auto]], or if the lambda
|
| 66 |
+
has a *template-parameter-list*.
|
| 67 |
+
|
| 68 |
+
[*Example 3*:
|
| 69 |
+
|
| 70 |
+
``` cpp
|
| 71 |
+
int i = [](int i, auto a) { return i; }(3, 4); // OK: a generic lambda
|
| 72 |
+
int j = []<class T>(T t, int i) { return i; }(3, 4); // OK: a generic lambda
|
| 73 |
+
```
|
| 74 |
+
|
| 75 |
+
— *end example*]
|
| 76 |
+
|
| 77 |
#### Closure types <a id="expr.prim.lambda.closure">[[expr.prim.lambda.closure]]</a>
|
| 78 |
|
| 79 |
The type of a *lambda-expression* (which is also the type of the closure
|
| 80 |
object) is a unique, unnamed non-union class type, called the *closure
|
| 81 |
type*, whose properties are described below.
|
| 82 |
|
| 83 |
The closure type is declared in the smallest block scope, class scope,
|
| 84 |
or namespace scope that contains the corresponding *lambda-expression*.
|
| 85 |
|
| 86 |
[*Note 1*: This determines the set of namespaces and classes associated
|
| 87 |
+
with the closure type [[basic.lookup.argdep]]. The parameter types of a
|
| 88 |
+
*lambda-declarator* do not affect these associated namespaces and
|
| 89 |
classes. — *end note*]
|
| 90 |
|
| 91 |
+
The closure type is not an aggregate type [[dcl.init.aggr]]. An
|
| 92 |
implementation may define the closure type differently from what is
|
| 93 |
described below provided this does not alter the observable behavior of
|
| 94 |
the program other than by changing:
|
| 95 |
|
| 96 |
- the size and/or alignment of the closure type,
|
| 97 |
+
- whether the closure type is trivially copyable [[class.prop]], or
|
| 98 |
+
- whether the closure type is a standard-layout class [[class.prop]].
|
|
|
|
|
|
|
| 99 |
|
| 100 |
An implementation shall not add members of rvalue reference type to the
|
| 101 |
closure type.
|
| 102 |
|
| 103 |
+
The closure type for a *lambda-expression* has a public inline function
|
| 104 |
+
call operator (for a non-generic lambda) or function call operator
|
| 105 |
+
template (for a generic lambda) [[over.call]] whose parameters and
|
| 106 |
return type are described by the *lambda-expression*’s
|
| 107 |
+
*parameter-declaration-clause* and *trailing-return-type* respectively,
|
| 108 |
+
and whose *template-parameter-list* consists of the specified
|
| 109 |
+
*template-parameter-list*, if any. The *requires-clause* of the function
|
| 110 |
+
call operator template is the *requires-clause* immediately following
|
| 111 |
+
`<` *template-parameter-list* `>`, if any. The trailing
|
| 112 |
+
*requires-clause* of the function call operator or operator template is
|
| 113 |
+
the *requires-clause* of the *lambda-declarator*, if any.
|
| 114 |
+
|
| 115 |
+
[*Note 2*: The function call operator template for a generic lambda
|
| 116 |
+
might be an abbreviated function template [[dcl.fct]]. — *end note*]
|
|
|
|
|
|
|
|
|
|
| 117 |
|
| 118 |
[*Example 1*:
|
| 119 |
|
| 120 |
``` cpp
|
| 121 |
auto glambda = [](auto a, auto&& b) { return a < b; };
|
|
|
|
| 146 |
call operator or operator template. An *attribute-specifier-seq* in a
|
| 147 |
*lambda-declarator* appertains to the type of the corresponding function
|
| 148 |
call operator or operator template. The function call operator or any
|
| 149 |
given operator template specialization is a constexpr function if either
|
| 150 |
the corresponding *lambda-expression*'s *parameter-declaration-clause*
|
| 151 |
+
is followed by `constexpr` or `consteval`, or it satisfies the
|
| 152 |
+
requirements for a constexpr function [[dcl.constexpr]]. It is an
|
| 153 |
+
immediate function [[dcl.constexpr]] if the corresponding
|
| 154 |
+
*lambda-expression*'s *parameter-declaration-clause* is followed by
|
| 155 |
+
`consteval`.
|
| 156 |
|
| 157 |
+
[*Note 3*: Names referenced in the *lambda-declarator* are looked up in
|
| 158 |
the context in which the *lambda-expression* appears. — *end note*]
|
| 159 |
|
| 160 |
[*Example 2*:
|
| 161 |
|
| 162 |
``` cpp
|
|
|
|
| 165 |
|
| 166 |
struct NonLiteral {
|
| 167 |
NonLiteral(int n) : n(n) { }
|
| 168 |
int n;
|
| 169 |
};
|
| 170 |
+
static_assert(ID(NonLiteral{3}).n == 3); // error
|
| 171 |
```
|
| 172 |
|
| 173 |
— *end example*]
|
| 174 |
|
| 175 |
[*Example 3*:
|
|
|
|
| 193 |
// Since two below is not declared constexpr, an evaluation of its constexpr member function call operator
|
| 194 |
// cannot perform an lvalue-to-rvalue conversion on one of its subobjects (that represents its capture)
|
| 195 |
// in a constant expression.
|
| 196 |
auto two = monoid(2);
|
| 197 |
assert(two() == 2); // OK, not a constant expression.
|
| 198 |
+
static_assert(add(one)(one)() == two()); // error: two() is not a constant expression
|
| 199 |
static_assert(add(one)(one)() == monoid(2)()); // OK
|
| 200 |
```
|
| 201 |
|
| 202 |
— *end example*]
|
| 203 |
|
| 204 |
+
[*Note 4*:
|
| 205 |
+
|
| 206 |
+
The function call operator or operator template may be constrained
|
| 207 |
+
[[temp.constr.decl]] by a *type-constraint* [[temp.param]], a
|
| 208 |
+
*requires-clause* [[temp.pre]], or a trailing *requires-clause*
|
| 209 |
+
[[dcl.decl]].
|
| 210 |
+
|
| 211 |
+
[*Example 4*:
|
| 212 |
+
|
| 213 |
+
``` cpp
|
| 214 |
+
template <typename T> concept C1 = ...;
|
| 215 |
+
template <std::size_t N> concept C2 = ...;
|
| 216 |
+
template <typename A, typename B> concept C3 = ...;
|
| 217 |
+
|
| 218 |
+
auto f = []<typename T1, C1 T2> requires C2<sizeof(T1) + sizeof(T2)>
|
| 219 |
+
(T1 a1, T1 b1, T2 a2, auto a3, auto a4) requires C3<decltype(a4), T2> {
|
| 220 |
+
// T2 is constrained by a type-constraint.
|
| 221 |
+
// T1 and T2 are constrained by a requires-clause, and
|
| 222 |
+
// T2 and the type of a4 are constrained by a trailing requires-clause.
|
| 223 |
+
};
|
| 224 |
+
```
|
| 225 |
+
|
| 226 |
+
— *end example*]
|
| 227 |
+
|
| 228 |
+
— *end note*]
|
| 229 |
+
|
| 230 |
The closure type for a non-generic *lambda-expression* with no
|
| 231 |
+
*lambda-capture* whose constraints (if any) are satisfied has a
|
| 232 |
+
conversion function to pointer to function with C++ language linkage
|
| 233 |
+
[[dcl.link]] having the same parameter and return types as the closure
|
| 234 |
+
type’s function call operator. The conversion is to “pointer to
|
| 235 |
+
`noexcept` function” if the function call operator has a non-throwing
|
| 236 |
+
exception specification. The value returned by this conversion function
|
| 237 |
+
is the address of a function `F` that, when invoked, has the same effect
|
| 238 |
+
as invoking the closure type’s function call operator on a
|
| 239 |
+
default-constructed instance of the closure type. `F` is a constexpr
|
| 240 |
+
function if the function call operator is a constexpr function and is an
|
| 241 |
+
immediate function if the function call operator is an immediate
|
| 242 |
+
function.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
|
| 244 |
+
For a generic lambda with no *lambda-capture*, the closure type has a
|
| 245 |
+
conversion function template to pointer to function. The conversion
|
| 246 |
+
function template has the same invented template parameter list, and the
|
| 247 |
+
pointer to function has the same parameter types, as the function call
|
| 248 |
+
operator template. The return type of the pointer to function shall
|
| 249 |
+
behave as if it were a *decltype-specifier* denoting the return type of
|
| 250 |
+
the corresponding function call operator template specialization.
|
| 251 |
+
|
| 252 |
+
[*Note 5*:
|
| 253 |
|
| 254 |
If the generic lambda has no *trailing-return-type* or the
|
| 255 |
*trailing-return-type* contains a placeholder type, return type
|
| 256 |
deduction of the corresponding function call operator template
|
| 257 |
specialization has to be done. The corresponding specialization is that
|
|
|
|
| 283 |
};
|
| 284 |
```
|
| 285 |
|
| 286 |
— *end note*]
|
| 287 |
|
| 288 |
+
[*Example 5*:
|
| 289 |
|
| 290 |
``` cpp
|
| 291 |
void f1(int (*)(int)) { }
|
| 292 |
void f2(char (*)(int)) { }
|
| 293 |
|
|
|
|
| 308 |
— *end example*]
|
| 309 |
|
| 310 |
The value returned by any given specialization of this conversion
|
| 311 |
function template is the address of a function `F` that, when invoked,
|
| 312 |
has the same effect as invoking the generic lambda’s corresponding
|
| 313 |
+
function call operator template specialization on a default-constructed
|
| 314 |
+
instance of the closure type. `F` is a constexpr function if the
|
| 315 |
+
corresponding specialization is a constexpr function and `F` is an
|
| 316 |
+
immediate function if the function call operator template specialization
|
| 317 |
+
is an immediate function.
|
| 318 |
|
| 319 |
+
[*Note 6*: This will result in the implicit instantiation of the
|
| 320 |
generic lambda’s body. The instantiated generic lambda’s return type and
|
| 321 |
+
parameter types are required to match the return type and parameter
|
| 322 |
+
types of the pointer to function. — *end note*]
|
| 323 |
|
| 324 |
+
[*Example 6*:
|
| 325 |
|
| 326 |
``` cpp
|
| 327 |
auto GL = [](auto a) { std::cout << a; return a; };
|
| 328 |
int (*GL_int)(int) = GL; // OK: through conversion function template
|
| 329 |
GL_int(3); // OK: same as GL(3)
|
|
|
|
| 331 |
|
| 332 |
— *end example*]
|
| 333 |
|
| 334 |
The conversion function or conversion function template is public,
|
| 335 |
constexpr, non-virtual, non-explicit, const, and has a non-throwing
|
| 336 |
+
exception specification [[except.spec]].
|
| 337 |
|
| 338 |
+
[*Example 7*:
|
| 339 |
|
| 340 |
``` cpp
|
| 341 |
auto Fwd = [](int (*fp)(int), auto a) { return fp(a); };
|
| 342 |
auto C = [](auto a) { return a; };
|
| 343 |
|
| 344 |
static_assert(Fwd(C,3) == 3); // OK
|
| 345 |
|
| 346 |
// No specialization of the function call operator template can be constexpr (due to the local static).
|
| 347 |
auto NC = [](auto a) { static int s; return a; };
|
| 348 |
+
static_assert(Fwd(NC,3) == 3); // error
|
| 349 |
```
|
| 350 |
|
| 351 |
— *end example*]
|
| 352 |
|
| 353 |
The *lambda-expression*’s *compound-statement* yields the
|
| 354 |
+
*function-body* [[dcl.fct.def]] of the function call operator, but for
|
| 355 |
+
purposes of name lookup [[basic.lookup]], determining the type and value
|
| 356 |
+
of `this` [[class.this]] and transforming *id-expression*s referring to
|
| 357 |
+
non-static class members into class member access expressions using
|
| 358 |
+
`(*this)` ([[class.mfct.non-static]]), the *compound-statement* is
|
| 359 |
+
considered in the context of the *lambda-expression*.
|
|
|
|
| 360 |
|
| 361 |
+
[*Example 8*:
|
| 362 |
|
| 363 |
``` cpp
|
| 364 |
struct S1 {
|
| 365 |
int x, y;
|
| 366 |
int operator()(int);
|
|
|
|
| 378 |
Further, a variable `__func__` is implicitly defined at the beginning of
|
| 379 |
the *compound-statement* of the *lambda-expression*, with semantics as
|
| 380 |
described in [[dcl.fct.def.general]].
|
| 381 |
|
| 382 |
The closure type associated with a *lambda-expression* has no default
|
| 383 |
+
constructor if the *lambda-expression* has a *lambda-capture* and a
|
| 384 |
+
defaulted default constructor otherwise. It has a defaulted copy
|
| 385 |
+
constructor and a defaulted move constructor [[class.copy.ctor]]. It has
|
| 386 |
+
a deleted copy assignment operator if the *lambda-expression* has a
|
| 387 |
+
*lambda-capture* and defaulted copy and move assignment operators
|
| 388 |
+
otherwise [[class.copy.assign]].
|
| 389 |
|
| 390 |
+
[*Note 7*: These special member functions are implicitly defined as
|
| 391 |
usual, and might therefore be defined as deleted. — *end note*]
|
| 392 |
|
| 393 |
The closure type associated with a *lambda-expression* has an
|
| 394 |
+
implicitly-declared destructor [[class.dtor]].
|
| 395 |
|
| 396 |
+
A member of a closure type shall not be explicitly instantiated
|
| 397 |
+
[[temp.explicit]], explicitly specialized [[temp.expl.spec]], or named
|
| 398 |
+
in a friend declaration [[class.friend]].
|
| 399 |
|
| 400 |
#### Captures <a id="expr.prim.lambda.capture">[[expr.prim.lambda.capture]]</a>
|
| 401 |
|
| 402 |
``` bnf
|
| 403 |
lambda-capture:
|
|
|
|
| 412 |
'='
|
| 413 |
```
|
| 414 |
|
| 415 |
``` bnf
|
| 416 |
capture-list:
|
| 417 |
+
capture
|
| 418 |
+
capture-list ',' capture
|
| 419 |
```
|
| 420 |
|
| 421 |
``` bnf
|
| 422 |
capture:
|
| 423 |
simple-capture
|
| 424 |
init-capture
|
| 425 |
```
|
| 426 |
|
| 427 |
``` bnf
|
| 428 |
simple-capture:
|
| 429 |
+
identifier '...'ₒₚₜ
|
| 430 |
+
'&' identifier '...'ₒₚₜ
|
| 431 |
+
this
|
| 432 |
+
'*' 'this'
|
| 433 |
```
|
| 434 |
|
| 435 |
``` bnf
|
| 436 |
init-capture:
|
| 437 |
+
'...'ₒₚₜ identifier initializer
|
| 438 |
+
'&' '...'ₒₚₜ identifier initializer
|
| 439 |
```
|
| 440 |
|
| 441 |
The body of a *lambda-expression* may refer to variables with automatic
|
| 442 |
storage duration and the `*this` object (if any) of enclosing block
|
| 443 |
scopes by capturing those entities, as described below.
|
| 444 |
|
| 445 |
If a *lambda-capture* includes a *capture-default* that is `&`, no
|
| 446 |
identifier in a *simple-capture* of that *lambda-capture* shall be
|
| 447 |
preceded by `&`. If a *lambda-capture* includes a *capture-default* that
|
| 448 |
is `=`, each *simple-capture* of that *lambda-capture* shall be of the
|
| 449 |
+
form “`&` *identifier* `...`ₒₚₜ ”, “`this`”, or “`* this`”.
|
| 450 |
|
| 451 |
[*Note 1*: The form `[&,this]` is redundant but accepted for
|
| 452 |
compatibility with ISO C++14. — *end note*]
|
| 453 |
|
| 454 |
Ignoring appearances in *initializer*s of *init-capture*s, an identifier
|
|
|
|
| 458 |
|
| 459 |
``` cpp
|
| 460 |
struct S2 { void f(int i); };
|
| 461 |
void S2::f(int i) {
|
| 462 |
[&, i]{ }; // OK
|
| 463 |
+
[&, this, i]{ }; // OK, equivalent to [&, i]
|
| 464 |
[&, &i]{ }; // error: i preceded by & when & is the default
|
| 465 |
[=, *this]{ }; // OK
|
| 466 |
+
[=, this]{ }; // OK, equivalent to [=]
|
| 467 |
[i, i]{ }; // error: i repeated
|
| 468 |
[this, *this]{ }; // error: this appears twice
|
| 469 |
}
|
| 470 |
```
|
| 471 |
|
| 472 |
— *end example*]
|
| 473 |
|
| 474 |
+
A *lambda-expression* shall not have a *capture-default* or
|
| 475 |
+
*simple-capture* in its *lambda-introducer* unless its innermost
|
| 476 |
+
enclosing scope is a block scope [[basic.scope.block]] or it appears
|
| 477 |
+
within a default member initializer and its innermost enclosing scope is
|
| 478 |
+
the corresponding class scope [[basic.scope.class]].
|
|
|
|
|
|
|
|
|
|
|
|
|
| 479 |
|
| 480 |
The *identifier* in a *simple-capture* is looked up using the usual
|
| 481 |
+
rules for unqualified name lookup [[basic.lookup.unqual]]; each such
|
| 482 |
+
lookup shall find a local entity. The *simple-capture*s `this` and
|
| 483 |
+
`* this` denote the local entity `*this`. An entity that is designated
|
| 484 |
+
by a *simple-capture* is said to be *explicitly captured*.
|
|
|
|
|
|
|
| 485 |
|
| 486 |
If an *identifier* in a *simple-capture* appears as the *declarator-id*
|
| 487 |
of a parameter of the *lambda-declarator*'s
|
| 488 |
*parameter-declaration-clause*, the program is ill-formed.
|
| 489 |
|
| 490 |
[*Example 2*:
|
| 491 |
|
| 492 |
``` cpp
|
| 493 |
void f() {
|
| 494 |
int x = 0;
|
| 495 |
+
auto g = [x](int x) { return 0; }; // error: parameter and simple-capture have the same name
|
| 496 |
}
|
| 497 |
```
|
| 498 |
|
| 499 |
— *end example*]
|
| 500 |
|
| 501 |
+
An *init-capture* without ellipsis behaves as if it declares and
|
| 502 |
+
explicitly captures a variable of the form “`auto` *init-capture* `;`”
|
| 503 |
+
whose declarative region is the *lambda-expression*’s
|
| 504 |
+
*compound-statement*, except that:
|
| 505 |
|
| 506 |
- if the capture is by copy (see below), the non-static data member
|
| 507 |
declared for the capture and the variable are treated as two different
|
| 508 |
ways of referring to the same object, which has the lifetime of the
|
| 509 |
non-static data member, and no additional copy and destruction is
|
| 510 |
performed, and
|
| 511 |
- if the capture is by reference, the variable’s lifetime ends when the
|
| 512 |
closure object’s lifetime ends.
|
| 513 |
|
| 514 |
+
[*Note 2*: This enables an *init-capture* like “`x = std::move(x)`”;
|
| 515 |
the second “`x`” must bind to a declaration in the surrounding
|
| 516 |
context. — *end note*]
|
| 517 |
|
| 518 |
[*Example 3*:
|
| 519 |
|
|
|
|
| 522 |
auto y = [&r = x, x = x+1]()->int {
|
| 523 |
r += 2;
|
| 524 |
return x+2;
|
| 525 |
}(); // Updates ::x to 6, and initializes y to 7.
|
| 526 |
|
| 527 |
+
auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
|
| 528 |
```
|
| 529 |
|
| 530 |
— *end example*]
|
| 531 |
|
| 532 |
+
For the purposes of lambda capture, an expression potentially references
|
| 533 |
+
local entities as follows:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 534 |
|
| 535 |
+
- An *id-expression* that names a local entity potentially references
|
| 536 |
+
that entity; an *id-expression* that names one or more non-static
|
| 537 |
+
class members and does not form a pointer to member [[expr.unary.op]]
|
| 538 |
+
potentially references `*this`. \[*Note 3*: This occurs even if
|
| 539 |
+
overload resolution selects a static member function for the
|
| 540 |
+
*id-expression*. — *end note*]
|
| 541 |
+
- A `this` expression potentially references `*this`.
|
| 542 |
+
- A *lambda-expression* potentially references the local entities named
|
| 543 |
+
by its *simple-capture*s.
|
| 544 |
+
|
| 545 |
+
If an expression potentially references a local entity within a
|
| 546 |
+
declarative region in which it is odr-usable, and the expression would
|
| 547 |
+
be potentially evaluated if the effect of any enclosing `typeid`
|
| 548 |
+
expressions [[expr.typeid]] were ignored, the entity is said to be
|
| 549 |
+
*implicitly captured* by each intervening *lambda-expression* with an
|
| 550 |
+
associated *capture-default* that does not explicitly capture it. The
|
| 551 |
+
implicit capture of `*this` is deprecated when the *capture-default* is
|
| 552 |
+
`=`; see [[depr.capture.this]].
|
| 553 |
|
| 554 |
[*Example 4*:
|
| 555 |
|
| 556 |
``` cpp
|
| 557 |
+
void f(int, const int (&)[2] = {}); // #1
|
| 558 |
+
void f(const int&, const int (&)[1]); // #2
|
| 559 |
void test() {
|
| 560 |
const int x = 17;
|
| 561 |
auto g = [](auto a) {
|
| 562 |
f(x); // OK: calls #1, does not capture x
|
| 563 |
};
|
| 564 |
|
| 565 |
+
auto g1 = [=](auto a) {
|
| 566 |
+
f(x); // OK: calls #1, captures x
|
| 567 |
+
};
|
| 568 |
+
|
| 569 |
auto g2 = [=](auto a) {
|
| 570 |
int selector[sizeof(a) == 1 ? 1 : 2]{};
|
| 571 |
+
f(x, selector); // OK: captures x, might call #1 or #2
|
| 572 |
+
};
|
| 573 |
+
|
| 574 |
+
auto g3 = [=](auto a) {
|
| 575 |
+
typeid(a + x); // captures x regardless of whether a + x is an unevaluated operand
|
| 576 |
};
|
| 577 |
}
|
| 578 |
```
|
| 579 |
|
| 580 |
+
Within `g1`, an implementation might optimize away the capture of `x` as
|
| 581 |
+
it is not odr-used.
|
| 582 |
+
|
| 583 |
— *end example*]
|
| 584 |
|
| 585 |
+
[*Note 4*:
|
| 586 |
+
|
| 587 |
+
The set of captured entities is determined syntactically, and entities
|
| 588 |
+
might be implicitly captured even if the expression denoting a local
|
| 589 |
+
entity is within a discarded statement [[stmt.if]].
|
| 590 |
+
|
| 591 |
+
[*Example 5*:
|
| 592 |
+
|
| 593 |
+
``` cpp
|
| 594 |
+
template<bool B>
|
| 595 |
+
void f(int n) {
|
| 596 |
+
[=](auto a) {
|
| 597 |
+
if constexpr (B && sizeof(a) > 4) {
|
| 598 |
+
(void)n; // captures n regardless of the value of B and sizeof(int)
|
| 599 |
+
}
|
| 600 |
+
}(0);
|
| 601 |
+
}
|
| 602 |
+
```
|
| 603 |
+
|
| 604 |
+
— *end example*]
|
| 605 |
|
| 606 |
+
— *end note*]
|
|
|
|
|
|
|
|
|
|
| 607 |
|
| 608 |
An entity is *captured* if it is captured explicitly or implicitly. An
|
| 609 |
+
entity captured by a *lambda-expression* is odr-used [[basic.def.odr]]
|
| 610 |
+
in the scope containing the *lambda-expression*.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 611 |
|
| 612 |
+
[*Note 5*: As a consequence, if a *lambda-expression* explicitly
|
| 613 |
+
captures an entity that is not odr-usable, the program is ill-formed
|
| 614 |
+
[[basic.def.odr]]. — *end note*]
|
| 615 |
+
|
| 616 |
+
[*Example 6*:
|
| 617 |
|
| 618 |
``` cpp
|
| 619 |
void f1(int i) {
|
| 620 |
int const N = 20;
|
| 621 |
auto m1 = [=]{
|
|
|
|
| 629 |
int f;
|
| 630 |
void work(int n) {
|
| 631 |
int m = n*n;
|
| 632 |
int j = 40;
|
| 633 |
auto m3 = [this,m] {
|
| 634 |
+
auto m4 = [&,j] { // error: j not odr-usable due to intervening lambda m3
|
| 635 |
+
int x = n; // error: n is odr-used but not odr-usable due to intervening lambda m3
|
| 636 |
x += m; // OK: m implicitly captured by m4 and explicitly captured by m3
|
| 637 |
+
x += i; // error: i is odr-used but not odr-usable
|
| 638 |
+
// due to intervening function and class scopes
|
| 639 |
x += f; // OK: this captured implicitly by m4 and explicitly by m3
|
| 640 |
};
|
| 641 |
};
|
| 642 |
}
|
| 643 |
};
|
|
|
|
| 647 |
double ohseven = .007;
|
| 648 |
auto f() {
|
| 649 |
return [this] {
|
| 650 |
return [*this] {
|
| 651 |
return ohseven; // OK
|
| 652 |
+
};
|
| 653 |
}();
|
| 654 |
}
|
| 655 |
auto g() {
|
| 656 |
return [] {
|
| 657 |
return [*this] { }; // error: *this not captured by outer lambda-expression
|
|
|
|
| 660 |
};
|
| 661 |
```
|
| 662 |
|
| 663 |
— *end example*]
|
| 664 |
|
| 665 |
+
[*Note 6*: Because local entities are not odr-usable within a default
|
| 666 |
+
argument [[basic.def.odr]], a *lambda-expression* appearing in a default
|
| 667 |
+
argument cannot implicitly or explicitly capture any local entity. Such
|
| 668 |
+
a *lambda-expression* can still have an *init-capture* if any
|
| 669 |
+
full-expression in its *initializer* satisfies the constraints of an
|
| 670 |
+
expression appearing in a default argument
|
| 671 |
+
[[dcl.fct.default]]. — *end note*]
|
| 672 |
|
| 673 |
+
[*Example 7*:
|
| 674 |
|
| 675 |
``` cpp
|
| 676 |
void f2() {
|
| 677 |
int i = 1;
|
| 678 |
+
void g1(int = ([i]{ return i; })()); // error
|
| 679 |
+
void g2(int = ([i]{ return 0; })()); // error
|
| 680 |
+
void g3(int = ([=]{ return i; })()); // error
|
| 681 |
void g4(int = ([=]{ return 0; })()); // OK
|
| 682 |
void g5(int = ([]{ return sizeof i; })()); // OK
|
| 683 |
+
void g6(int = ([x=1]{ return x; })()); // OK
|
| 684 |
+
void g7(int = ([x=i]{ return x; })()); // error
|
| 685 |
}
|
| 686 |
```
|
| 687 |
|
| 688 |
— *end example*]
|
| 689 |
|
|
|
|
| 701 |
referenced function type if the entity is a reference to a function, or
|
| 702 |
the type of the corresponding captured entity otherwise. A member of an
|
| 703 |
anonymous union shall not be captured by copy.
|
| 704 |
|
| 705 |
Every *id-expression* within the *compound-statement* of a
|
| 706 |
+
*lambda-expression* that is an odr-use [[basic.def.odr]] of an entity
|
| 707 |
captured by copy is transformed into an access to the corresponding
|
| 708 |
unnamed data member of the closure type.
|
| 709 |
|
| 710 |
+
[*Note 7*: An *id-expression* that is not an odr-use refers to the
|
| 711 |
+
original entity, never to a member of the closure type. However, such an
|
| 712 |
+
*id-expression* can still cause the implicit capture of the
|
| 713 |
entity. — *end note*]
|
| 714 |
|
| 715 |
+
If `*this` is captured by copy, each expression that odr-uses `*this` is
|
| 716 |
+
transformed to instead refer to the corresponding unnamed data member of
|
| 717 |
+
the closure type.
|
| 718 |
|
| 719 |
+
[*Example 8*:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 720 |
|
| 721 |
``` cpp
|
| 722 |
void f(const int*);
|
| 723 |
void g() {
|
| 724 |
const int N = 10;
|
|
|
|
| 726 |
int arr[N]; // OK: not an odr-use, refers to automatic variable
|
| 727 |
f(&N); // OK: causes N to be captured; &N points to
|
| 728 |
// the corresponding member of the closure type
|
| 729 |
};
|
| 730 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 731 |
```
|
| 732 |
|
| 733 |
— *end example*]
|
| 734 |
|
| 735 |
An entity is *captured by reference* if it is implicitly or explicitly
|
| 736 |
captured but not captured by copy. It is unspecified whether additional
|
| 737 |
unnamed non-static data members are declared in the closure type for
|
| 738 |
entities captured by reference. If declared, such non-static data
|
| 739 |
members shall be of literal type.
|
| 740 |
|
| 741 |
+
[*Example 9*:
|
| 742 |
|
| 743 |
``` cpp
|
| 744 |
// The inner closure type must be a literal type regardless of how reference captures are represented.
|
| 745 |
static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4);
|
| 746 |
```
|
|
|
|
| 748 |
— *end example*]
|
| 749 |
|
| 750 |
A bit-field or a member of an anonymous union shall not be captured by
|
| 751 |
reference.
|
| 752 |
|
| 753 |
+
An *id-expression* within the *compound-statement* of a
|
| 754 |
+
*lambda-expression* that is an odr-use of a reference captured by
|
| 755 |
+
reference refers to the entity to which the captured reference is bound
|
| 756 |
+
and not to the captured reference.
|
| 757 |
+
|
| 758 |
+
[*Note 8*: The validity of such captures is determined by the lifetime
|
| 759 |
+
of the object to which the reference refers, not by the lifetime of the
|
| 760 |
+
reference itself. — *end note*]
|
| 761 |
+
|
| 762 |
+
[*Example 10*:
|
| 763 |
+
|
| 764 |
+
``` cpp
|
| 765 |
+
auto h(int &r) {
|
| 766 |
+
return [&] {
|
| 767 |
+
++r; // Valid after h returns if the lifetime of the
|
| 768 |
+
// object to which r is bound has not ended
|
| 769 |
+
};
|
| 770 |
+
}
|
| 771 |
+
```
|
| 772 |
+
|
| 773 |
+
— *end example*]
|
| 774 |
+
|
| 775 |
If a *lambda-expression* `m2` captures an entity and that entity is
|
| 776 |
captured by an immediately enclosing *lambda-expression* `m1`, then
|
| 777 |
`m2`’s capture is transformed as follows:
|
| 778 |
|
| 779 |
- if `m1` captures the entity by copy, `m2` captures the corresponding
|
| 780 |
non-static data member of `m1`’s closure type;
|
| 781 |
- if `m1` captures the entity by reference, `m2` captures the same
|
| 782 |
entity captured by `m1`.
|
| 783 |
|
| 784 |
+
[*Example 11*:
|
| 785 |
|
| 786 |
+
The nested *lambda-expression*s and invocations below will output
|
| 787 |
`123234`.
|
| 788 |
|
| 789 |
``` cpp
|
| 790 |
int a = 1, b = 1, c = 1;
|
| 791 |
auto m1 = [a, &b, &c]() mutable {
|
|
|
|
| 801 |
std::cout << a << b << c;
|
| 802 |
```
|
| 803 |
|
| 804 |
— *end example*]
|
| 805 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 806 |
When the *lambda-expression* is evaluated, the entities that are
|
| 807 |
captured by copy are used to direct-initialize each corresponding
|
| 808 |
non-static data member of the resulting closure object, and the
|
| 809 |
non-static data members corresponding to the *init-capture*s are
|
| 810 |
initialized as indicated by the corresponding *initializer* (which may
|
| 811 |
be copy- or direct-initialization). (For array members, the array
|
| 812 |
elements are direct-initialized in increasing subscript order.) These
|
| 813 |
initializations are performed in the (unspecified) order in which the
|
| 814 |
non-static data members are declared.
|
| 815 |
|
| 816 |
+
[*Note 9*: This ensures that the destructions will occur in the reverse
|
| 817 |
order of the constructions. — *end note*]
|
| 818 |
|
| 819 |
+
[*Note 10*: If a non-reference entity is implicitly or explicitly
|
| 820 |
captured by reference, invoking the function call operator of the
|
| 821 |
corresponding *lambda-expression* after the lifetime of the entity has
|
| 822 |
ended is likely to result in undefined behavior. — *end note*]
|
| 823 |
|
| 824 |
+
A *simple-capture* containing an ellipsis is a pack expansion
|
| 825 |
+
[[temp.variadic]]. An *init-capture* containing an ellipsis is a pack
|
| 826 |
+
expansion that introduces an *init-capture* pack [[temp.variadic]] whose
|
| 827 |
+
declarative region is the *lambda-expression*’s *compound-statement*.
|
| 828 |
|
| 829 |
+
[*Example 12*:
|
| 830 |
|
| 831 |
``` cpp
|
| 832 |
template<class... Args>
|
| 833 |
void f(Args... args) {
|
| 834 |
auto lm = [&, args...] { return g(args...); };
|
| 835 |
lm();
|
| 836 |
+
|
| 837 |
+
auto lm2 = [...xs=std::move(args)] { return g(xs...); };
|
| 838 |
+
lm2();
|
| 839 |
}
|
| 840 |
```
|
| 841 |
|
| 842 |
— *end example*]
|
| 843 |
|