tmp/tmpoex98vh9/{from.md → to.md}
RENAMED
|
@@ -37,13 +37,12 @@ simple-capture:
|
|
| 37 |
init-capture:
|
| 38 |
'...'ₒₚₜ identifier initializer
|
| 39 |
'&' '...'ₒₚₜ identifier initializer
|
| 40 |
```
|
| 41 |
|
| 42 |
-
The body of a *lambda-expression* may refer to
|
| 43 |
-
|
| 44 |
-
scopes by capturing those entities, as described below.
|
| 45 |
|
| 46 |
If a *lambda-capture* includes a *capture-default* that is `&`, no
|
| 47 |
identifier in a *simple-capture* of that *lambda-capture* shall be
|
| 48 |
preceded by `&`. If a *lambda-capture* includes a *capture-default* that
|
| 49 |
is `=`, each *simple-capture* of that *lambda-capture* shall be of the
|
|
@@ -76,35 +75,37 @@ A *lambda-expression* shall not have a *capture-default* or
|
|
| 76 |
*simple-capture* in its *lambda-introducer* unless its innermost
|
| 77 |
enclosing scope is a block scope [[basic.scope.block]] or it appears
|
| 78 |
within a default member initializer and its innermost enclosing scope is
|
| 79 |
the corresponding class scope [[basic.scope.class]].
|
| 80 |
|
| 81 |
-
The *identifier* in a *simple-capture*
|
| 82 |
-
|
| 83 |
-
lookup shall find a local entity. The *simple-capture*s `this` and
|
| 84 |
`* this` denote the local entity `*this`. An entity that is designated
|
| 85 |
by a *simple-capture* is said to be *explicitly captured*.
|
| 86 |
|
| 87 |
-
If an *identifier* in a *
|
| 88 |
-
|
| 89 |
-
|
|
|
|
| 90 |
|
| 91 |
[*Example 2*:
|
| 92 |
|
| 93 |
``` cpp
|
| 94 |
void f() {
|
| 95 |
int x = 0;
|
| 96 |
-
auto g = [x](int x) { return 0; }; // error: parameter and
|
|
|
|
|
|
|
| 97 |
}
|
| 98 |
```
|
| 99 |
|
| 100 |
— *end example*]
|
| 101 |
|
| 102 |
-
An *init-capture*
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
*
|
| 106 |
|
| 107 |
- if the capture is by copy (see below), the non-static data member
|
| 108 |
declared for the capture and the variable are treated as two different
|
| 109 |
ways of referring to the same object, which has the lifetime of the
|
| 110 |
non-static data member, and no additional copy and destruction is
|
|
@@ -123,11 +124,14 @@ int x = 4;
|
|
| 123 |
auto y = [&r = x, x = x+1]()->int {
|
| 124 |
r += 2;
|
| 125 |
return x+2;
|
| 126 |
}(); // Updates ::x to 6, and initializes y to 7.
|
| 127 |
|
| 128 |
-
auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
|
|
|
|
|
|
|
|
|
|
| 129 |
```
|
| 130 |
|
| 131 |
— *end example*]
|
| 132 |
|
| 133 |
For the purposes of lambda capture, an expression potentially references
|
|
@@ -141,13 +145,13 @@ local entities as follows:
|
|
| 141 |
*id-expression*. — *end note*]
|
| 142 |
- A `this` expression potentially references `*this`.
|
| 143 |
- A *lambda-expression* potentially references the local entities named
|
| 144 |
by its *simple-capture*s.
|
| 145 |
|
| 146 |
-
If an expression potentially references a local entity within a
|
| 147 |
-
|
| 148 |
-
|
| 149 |
expressions [[expr.typeid]] were ignored, the entity is said to be
|
| 150 |
*implicitly captured* by each intervening *lambda-expression* with an
|
| 151 |
associated *capture-default* that does not explicitly capture it. The
|
| 152 |
implicit capture of `*this` is deprecated when the *capture-default* is
|
| 153 |
`=`; see [[depr.capture.this]].
|
|
@@ -158,38 +162,38 @@ implicit capture of `*this` is deprecated when the *capture-default* is
|
|
| 158 |
void f(int, const int (&)[2] = {}); // #1
|
| 159 |
void f(const int&, const int (&)[1]); // #2
|
| 160 |
void test() {
|
| 161 |
const int x = 17;
|
| 162 |
auto g = [](auto a) {
|
| 163 |
-
f(x); // OK
|
| 164 |
};
|
| 165 |
|
| 166 |
auto g1 = [=](auto a) {
|
| 167 |
-
f(x); // OK
|
| 168 |
};
|
| 169 |
|
| 170 |
auto g2 = [=](auto a) {
|
| 171 |
int selector[sizeof(a) == 1 ? 1 : 2]{};
|
| 172 |
-
f(x, selector); // OK
|
| 173 |
};
|
| 174 |
|
| 175 |
auto g3 = [=](auto a) {
|
| 176 |
typeid(a + x); // captures x regardless of whether a + x is an unevaluated operand
|
| 177 |
};
|
| 178 |
}
|
| 179 |
```
|
| 180 |
|
| 181 |
-
Within `g1`, an implementation
|
| 182 |
it is not odr-used.
|
| 183 |
|
| 184 |
— *end example*]
|
| 185 |
|
| 186 |
[*Note 4*:
|
| 187 |
|
| 188 |
The set of captured entities is determined syntactically, and entities
|
| 189 |
-
|
| 190 |
-
|
| 191 |
|
| 192 |
[*Example 5*:
|
| 193 |
|
| 194 |
``` cpp
|
| 195 |
template<bool B>
|
|
@@ -205,12 +209,12 @@ void f(int n) {
|
|
| 205 |
— *end example*]
|
| 206 |
|
| 207 |
— *end note*]
|
| 208 |
|
| 209 |
An entity is *captured* if it is captured explicitly or implicitly. An
|
| 210 |
-
entity captured by a *lambda-expression* is odr-used [[
|
| 211 |
-
|
| 212 |
|
| 213 |
[*Note 5*: As a consequence, if a *lambda-expression* explicitly
|
| 214 |
captures an entity that is not odr-usable, the program is ill-formed
|
| 215 |
[[basic.def.odr]]. — *end note*]
|
| 216 |
|
|
@@ -220,26 +224,26 @@ captures an entity that is not odr-usable, the program is ill-formed
|
|
| 220 |
void f1(int i) {
|
| 221 |
int const N = 20;
|
| 222 |
auto m1 = [=]{
|
| 223 |
int const M = 30;
|
| 224 |
auto m2 = [i]{
|
| 225 |
-
int x[N][M]; // OK
|
| 226 |
-
x[0][0] = i; // OK
|
| 227 |
};
|
| 228 |
};
|
| 229 |
struct s1 {
|
| 230 |
int f;
|
| 231 |
void work(int n) {
|
| 232 |
int m = n*n;
|
| 233 |
int j = 40;
|
| 234 |
auto m3 = [this,m] {
|
| 235 |
auto m4 = [&,j] { // error: j not odr-usable due to intervening lambda m3
|
| 236 |
int x = n; // error: n is odr-used but not odr-usable due to intervening lambda m3
|
| 237 |
-
x += m; // OK
|
| 238 |
x += i; // error: i is odr-used but not odr-usable
|
| 239 |
// due to intervening function and class scopes
|
| 240 |
-
x += f; // OK
|
| 241 |
};
|
| 242 |
};
|
| 243 |
}
|
| 244 |
};
|
| 245 |
}
|
|
@@ -302,11 +306,11 @@ the entity is a reference to an object, an lvalue reference to the
|
|
| 302 |
referenced function type if the entity is a reference to a function, or
|
| 303 |
the type of the corresponding captured entity otherwise. A member of an
|
| 304 |
anonymous union shall not be captured by copy.
|
| 305 |
|
| 306 |
Every *id-expression* within the *compound-statement* of a
|
| 307 |
-
*lambda-expression* that is an odr-use [[
|
| 308 |
captured by copy is transformed into an access to the corresponding
|
| 309 |
unnamed data member of the closure type.
|
| 310 |
|
| 311 |
[*Note 7*: An *id-expression* that is not an odr-use refers to the
|
| 312 |
original entity, never to a member of the closure type. However, such an
|
|
@@ -322,12 +326,12 @@ the closure type.
|
|
| 322 |
``` cpp
|
| 323 |
void f(const int*);
|
| 324 |
void g() {
|
| 325 |
const int N = 10;
|
| 326 |
[=] {
|
| 327 |
-
int arr[N]; // OK
|
| 328 |
-
f(&N); // OK
|
| 329 |
// the corresponding member of the closure type
|
| 330 |
};
|
| 331 |
}
|
| 332 |
```
|
| 333 |
|
|
@@ -375,13 +379,15 @@ auto h(int &r) {
|
|
| 375 |
|
| 376 |
If a *lambda-expression* `m2` captures an entity and that entity is
|
| 377 |
captured by an immediately enclosing *lambda-expression* `m1`, then
|
| 378 |
`m2`’s capture is transformed as follows:
|
| 379 |
|
| 380 |
-
-
|
| 381 |
-
non-static data member of `m1`’s closure type;
|
| 382 |
-
|
|
|
|
|
|
|
| 383 |
entity captured by `m1`.
|
| 384 |
|
| 385 |
[*Example 11*:
|
| 386 |
|
| 387 |
The nested *lambda-expression*s and invocations below will output
|
|
@@ -422,12 +428,11 @@ captured by reference, invoking the function call operator of the
|
|
| 422 |
corresponding *lambda-expression* after the lifetime of the entity has
|
| 423 |
ended is likely to result in undefined behavior. — *end note*]
|
| 424 |
|
| 425 |
A *simple-capture* containing an ellipsis is a pack expansion
|
| 426 |
[[temp.variadic]]. An *init-capture* containing an ellipsis is a pack
|
| 427 |
-
expansion that
|
| 428 |
-
declarative region is the *lambda-expression*’s *compound-statement*.
|
| 429 |
|
| 430 |
[*Example 12*:
|
| 431 |
|
| 432 |
``` cpp
|
| 433 |
template<class... Args>
|
|
|
|
| 37 |
init-capture:
|
| 38 |
'...'ₒₚₜ identifier initializer
|
| 39 |
'&' '...'ₒₚₜ identifier initializer
|
| 40 |
```
|
| 41 |
|
| 42 |
+
The body of a *lambda-expression* may refer to local entities of
|
| 43 |
+
enclosing block scopes by capturing those entities, as described below.
|
|
|
|
| 44 |
|
| 45 |
If a *lambda-capture* includes a *capture-default* that is `&`, no
|
| 46 |
identifier in a *simple-capture* of that *lambda-capture* shall be
|
| 47 |
preceded by `&`. If a *lambda-capture* includes a *capture-default* that
|
| 48 |
is `=`, each *simple-capture* of that *lambda-capture* shall be of the
|
|
|
|
| 75 |
*simple-capture* in its *lambda-introducer* unless its innermost
|
| 76 |
enclosing scope is a block scope [[basic.scope.block]] or it appears
|
| 77 |
within a default member initializer and its innermost enclosing scope is
|
| 78 |
the corresponding class scope [[basic.scope.class]].
|
| 79 |
|
| 80 |
+
The *identifier* in a *simple-capture* shall denote a local entity
|
| 81 |
+
[[basic.lookup.unqual]], [[basic.pre]]. The *simple-capture*s `this` and
|
|
|
|
| 82 |
`* this` denote the local entity `*this`. An entity that is designated
|
| 83 |
by a *simple-capture* is said to be *explicitly captured*.
|
| 84 |
|
| 85 |
+
If an *identifier* in a *capture* appears as the *declarator-id* of a
|
| 86 |
+
parameter of the *lambda-declarator*’s *parameter-declaration-clause* or
|
| 87 |
+
as the name of a template parameter of the *lambda-expression*’s
|
| 88 |
+
*template-parameter-list*, the program is ill-formed.
|
| 89 |
|
| 90 |
[*Example 2*:
|
| 91 |
|
| 92 |
``` cpp
|
| 93 |
void f() {
|
| 94 |
int x = 0;
|
| 95 |
+
auto g = [x](int x) { return 0; }; // error: parameter and capture have the same name
|
| 96 |
+
auto h = [y = 0]<typename y>(y) { return 0; }; // error: template parameter and capture
|
| 97 |
+
// have the same name
|
| 98 |
}
|
| 99 |
```
|
| 100 |
|
| 101 |
— *end example*]
|
| 102 |
|
| 103 |
+
An *init-capture* inhabits the lambda scope [[basic.scope.lambda]] of
|
| 104 |
+
the *lambda-expression*. An *init-capture* without ellipsis behaves as
|
| 105 |
+
if it declares and explicitly captures a variable of the form “`auto`
|
| 106 |
+
*init-capture* `;`”, except that:
|
| 107 |
|
| 108 |
- if the capture is by copy (see below), the non-static data member
|
| 109 |
declared for the capture and the variable are treated as two different
|
| 110 |
ways of referring to the same object, which has the lifetime of the
|
| 111 |
non-static data member, and no additional copy and destruction is
|
|
|
|
| 124 |
auto y = [&r = x, x = x+1]()->int {
|
| 125 |
r += 2;
|
| 126 |
return x+2;
|
| 127 |
}(); // Updates ::x to 6, and initializes y to 7.
|
| 128 |
|
| 129 |
+
auto z = [a = 42](int a) { return 1; }; // error: parameter and conceptual local variable have the same name
|
| 130 |
+
auto counter = [i=0]() mutable -> decltype(i) { // OK, returns int
|
| 131 |
+
return i++;
|
| 132 |
+
};
|
| 133 |
```
|
| 134 |
|
| 135 |
— *end example*]
|
| 136 |
|
| 137 |
For the purposes of lambda capture, an expression potentially references
|
|
|
|
| 145 |
*id-expression*. — *end note*]
|
| 146 |
- A `this` expression potentially references `*this`.
|
| 147 |
- A *lambda-expression* potentially references the local entities named
|
| 148 |
by its *simple-capture*s.
|
| 149 |
|
| 150 |
+
If an expression potentially references a local entity within a scope in
|
| 151 |
+
which it is odr-usable [[basic.def.odr]], and the expression would be
|
| 152 |
+
potentially evaluated if the effect of any enclosing `typeid`
|
| 153 |
expressions [[expr.typeid]] were ignored, the entity is said to be
|
| 154 |
*implicitly captured* by each intervening *lambda-expression* with an
|
| 155 |
associated *capture-default* that does not explicitly capture it. The
|
| 156 |
implicit capture of `*this` is deprecated when the *capture-default* is
|
| 157 |
`=`; see [[depr.capture.this]].
|
|
|
|
| 162 |
void f(int, const int (&)[2] = {}); // #1
|
| 163 |
void f(const int&, const int (&)[1]); // #2
|
| 164 |
void test() {
|
| 165 |
const int x = 17;
|
| 166 |
auto g = [](auto a) {
|
| 167 |
+
f(x); // OK, calls #1, does not capture x
|
| 168 |
};
|
| 169 |
|
| 170 |
auto g1 = [=](auto a) {
|
| 171 |
+
f(x); // OK, calls #1, captures x
|
| 172 |
};
|
| 173 |
|
| 174 |
auto g2 = [=](auto a) {
|
| 175 |
int selector[sizeof(a) == 1 ? 1 : 2]{};
|
| 176 |
+
f(x, selector); // OK, captures x, can call #1 or #2
|
| 177 |
};
|
| 178 |
|
| 179 |
auto g3 = [=](auto a) {
|
| 180 |
typeid(a + x); // captures x regardless of whether a + x is an unevaluated operand
|
| 181 |
};
|
| 182 |
}
|
| 183 |
```
|
| 184 |
|
| 185 |
+
Within `g1`, an implementation can optimize away the capture of `x` as
|
| 186 |
it is not odr-used.
|
| 187 |
|
| 188 |
— *end example*]
|
| 189 |
|
| 190 |
[*Note 4*:
|
| 191 |
|
| 192 |
The set of captured entities is determined syntactically, and entities
|
| 193 |
+
are implicitly captured even if the expression denoting a local entity
|
| 194 |
+
is within a discarded statement [[stmt.if]].
|
| 195 |
|
| 196 |
[*Example 5*:
|
| 197 |
|
| 198 |
``` cpp
|
| 199 |
template<bool B>
|
|
|
|
| 209 |
— *end example*]
|
| 210 |
|
| 211 |
— *end note*]
|
| 212 |
|
| 213 |
An entity is *captured* if it is captured explicitly or implicitly. An
|
| 214 |
+
entity captured by a *lambda-expression* is odr-used [[term.odr.use]] by
|
| 215 |
+
the *lambda-expression*.
|
| 216 |
|
| 217 |
[*Note 5*: As a consequence, if a *lambda-expression* explicitly
|
| 218 |
captures an entity that is not odr-usable, the program is ill-formed
|
| 219 |
[[basic.def.odr]]. — *end note*]
|
| 220 |
|
|
|
|
| 224 |
void f1(int i) {
|
| 225 |
int const N = 20;
|
| 226 |
auto m1 = [=]{
|
| 227 |
int const M = 30;
|
| 228 |
auto m2 = [i]{
|
| 229 |
+
int x[N][M]; // OK, N and M are not odr-used
|
| 230 |
+
x[0][0] = i; // OK, i is explicitly captured by m2 and implicitly captured by m1
|
| 231 |
};
|
| 232 |
};
|
| 233 |
struct s1 {
|
| 234 |
int f;
|
| 235 |
void work(int n) {
|
| 236 |
int m = n*n;
|
| 237 |
int j = 40;
|
| 238 |
auto m3 = [this,m] {
|
| 239 |
auto m4 = [&,j] { // error: j not odr-usable due to intervening lambda m3
|
| 240 |
int x = n; // error: n is odr-used but not odr-usable due to intervening lambda m3
|
| 241 |
+
x += m; // OK, m implicitly captured by m4 and explicitly captured by m3
|
| 242 |
x += i; // error: i is odr-used but not odr-usable
|
| 243 |
// due to intervening function and class scopes
|
| 244 |
+
x += f; // OK, this captured implicitly by m4 and explicitly by m3
|
| 245 |
};
|
| 246 |
};
|
| 247 |
}
|
| 248 |
};
|
| 249 |
}
|
|
|
|
| 306 |
referenced function type if the entity is a reference to a function, or
|
| 307 |
the type of the corresponding captured entity otherwise. A member of an
|
| 308 |
anonymous union shall not be captured by copy.
|
| 309 |
|
| 310 |
Every *id-expression* within the *compound-statement* of a
|
| 311 |
+
*lambda-expression* that is an odr-use [[term.odr.use]] of an entity
|
| 312 |
captured by copy is transformed into an access to the corresponding
|
| 313 |
unnamed data member of the closure type.
|
| 314 |
|
| 315 |
[*Note 7*: An *id-expression* that is not an odr-use refers to the
|
| 316 |
original entity, never to a member of the closure type. However, such an
|
|
|
|
| 326 |
``` cpp
|
| 327 |
void f(const int*);
|
| 328 |
void g() {
|
| 329 |
const int N = 10;
|
| 330 |
[=] {
|
| 331 |
+
int arr[N]; // OK, not an odr-use, refers to automatic variable
|
| 332 |
+
f(&N); // OK, causes N to be captured; &N points to
|
| 333 |
// the corresponding member of the closure type
|
| 334 |
};
|
| 335 |
}
|
| 336 |
```
|
| 337 |
|
|
|
|
| 379 |
|
| 380 |
If a *lambda-expression* `m2` captures an entity and that entity is
|
| 381 |
captured by an immediately enclosing *lambda-expression* `m1`, then
|
| 382 |
`m2`’s capture is transformed as follows:
|
| 383 |
|
| 384 |
+
- If `m1` captures the entity by copy, `m2` captures the corresponding
|
| 385 |
+
non-static data member of `m1`’s closure type; if `m1` is not
|
| 386 |
+
`mutable`, the non-static data member is considered to be
|
| 387 |
+
const-qualified.
|
| 388 |
+
- If `m1` captures the entity by reference, `m2` captures the same
|
| 389 |
entity captured by `m1`.
|
| 390 |
|
| 391 |
[*Example 11*:
|
| 392 |
|
| 393 |
The nested *lambda-expression*s and invocations below will output
|
|
|
|
| 428 |
corresponding *lambda-expression* after the lifetime of the entity has
|
| 429 |
ended is likely to result in undefined behavior. — *end note*]
|
| 430 |
|
| 431 |
A *simple-capture* containing an ellipsis is a pack expansion
|
| 432 |
[[temp.variadic]]. An *init-capture* containing an ellipsis is a pack
|
| 433 |
+
expansion that declares an *init-capture* pack [[temp.variadic]].
|
|
|
|
| 434 |
|
| 435 |
[*Example 12*:
|
| 436 |
|
| 437 |
``` cpp
|
| 438 |
template<class... Args>
|