tmp/tmp2ieqnjmr/{from.md → to.md}
RENAMED
|
@@ -0,0 +1,425 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#### Captures <a id="expr.prim.lambda.capture">[[expr.prim.lambda.capture]]</a>
|
| 2 |
+
|
| 3 |
+
``` bnf
|
| 4 |
+
lambda-capture:
|
| 5 |
+
capture-default
|
| 6 |
+
capture-list
|
| 7 |
+
capture-default ',' capture-list
|
| 8 |
+
```
|
| 9 |
+
|
| 10 |
+
``` bnf
|
| 11 |
+
capture-default:
|
| 12 |
+
'&'
|
| 13 |
+
'='
|
| 14 |
+
```
|
| 15 |
+
|
| 16 |
+
``` bnf
|
| 17 |
+
capture-list:
|
| 18 |
+
capture '...'ₒₚₜ
|
| 19 |
+
capture-list ',' capture '...'ₒₚₜ
|
| 20 |
+
```
|
| 21 |
+
|
| 22 |
+
``` bnf
|
| 23 |
+
capture:
|
| 24 |
+
simple-capture
|
| 25 |
+
init-capture
|
| 26 |
+
```
|
| 27 |
+
|
| 28 |
+
``` bnf
|
| 29 |
+
simple-capture:
|
| 30 |
+
identifier
|
| 31 |
+
'&' identifier
|
| 32 |
+
'this'
|
| 33 |
+
'* this'
|
| 34 |
+
```
|
| 35 |
+
|
| 36 |
+
``` bnf
|
| 37 |
+
init-capture:
|
| 38 |
+
identifier initializer
|
| 39 |
+
'&' identifier initializer
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
The body of a *lambda-expression* may refer to variables with automatic
|
| 43 |
+
storage duration and the `*this` object (if any) of enclosing block
|
| 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
|
| 50 |
+
form “`&` *identifier*” or “`* this`”.
|
| 51 |
+
|
| 52 |
+
[*Note 1*: The form `[&,this]` is redundant but accepted for
|
| 53 |
+
compatibility with ISO C++14. — *end note*]
|
| 54 |
+
|
| 55 |
+
Ignoring appearances in *initializer*s of *init-capture*s, an identifier
|
| 56 |
+
or `this` shall not appear more than once in a *lambda-capture*.
|
| 57 |
+
|
| 58 |
+
[*Example 1*:
|
| 59 |
+
|
| 60 |
+
``` cpp
|
| 61 |
+
struct S2 { void f(int i); };
|
| 62 |
+
void S2::f(int i) {
|
| 63 |
+
[&, i]{ }; // OK
|
| 64 |
+
[&, &i]{ }; // error: i preceded by & when & is the default
|
| 65 |
+
[=, *this]{ }; // OK
|
| 66 |
+
[=, this]{ }; // error: this when = is the default
|
| 67 |
+
[i, i]{ }; // error: i repeated
|
| 68 |
+
[this, *this]{ }; // error: this appears twice
|
| 69 |
+
}
|
| 70 |
+
```
|
| 71 |
+
|
| 72 |
+
— *end example*]
|
| 73 |
+
|
| 74 |
+
A *lambda-expression* whose smallest enclosing scope is a block scope (
|
| 75 |
+
[[basic.scope.block]]) is a *local lambda expression*; any other
|
| 76 |
+
*lambda-expression* shall not have a *capture-default* or
|
| 77 |
+
*simple-capture* in its *lambda-introducer*. The *reaching scope* of a
|
| 78 |
+
local lambda expression is the set of enclosing scopes up to and
|
| 79 |
+
including the innermost enclosing function and its parameters.
|
| 80 |
+
|
| 81 |
+
[*Note 2*: This reaching scope includes any intervening
|
| 82 |
+
*lambda-expression*s. — *end note*]
|
| 83 |
+
|
| 84 |
+
The *identifier* in a *simple-capture* is looked up using the usual
|
| 85 |
+
rules for unqualified name lookup ([[basic.lookup.unqual]]); each such
|
| 86 |
+
lookup shall find an entity. An entity that is designated by a
|
| 87 |
+
*simple-capture* is said to be *explicitly captured*, and shall be
|
| 88 |
+
`*this` (when the *simple-capture* is “`this`” or “`* this`”) or a
|
| 89 |
+
variable with automatic storage duration declared in the reaching scope
|
| 90 |
+
of the local lambda expression.
|
| 91 |
+
|
| 92 |
+
If an *identifier* in a *simple-capture* appears as the *declarator-id*
|
| 93 |
+
of a parameter of the *lambda-declarator*'s
|
| 94 |
+
*parameter-declaration-clause*, the program is ill-formed.
|
| 95 |
+
|
| 96 |
+
[*Example 2*:
|
| 97 |
+
|
| 98 |
+
``` cpp
|
| 99 |
+
void f() {
|
| 100 |
+
int x = 0;
|
| 101 |
+
auto g = [x](int x) { return 0; } // error: parameter and simple-capture have the same name
|
| 102 |
+
}
|
| 103 |
+
```
|
| 104 |
+
|
| 105 |
+
— *end example*]
|
| 106 |
+
|
| 107 |
+
An *init-capture* behaves as if it declares and explicitly captures a
|
| 108 |
+
variable of the form “`auto` *init-capture* `;`” whose declarative
|
| 109 |
+
region is the *lambda-expression*’s *compound-statement*, except that:
|
| 110 |
+
|
| 111 |
+
- if the capture is by copy (see below), the non-static data member
|
| 112 |
+
declared for the capture and the variable are treated as two different
|
| 113 |
+
ways of referring to the same object, which has the lifetime of the
|
| 114 |
+
non-static data member, and no additional copy and destruction is
|
| 115 |
+
performed, and
|
| 116 |
+
- if the capture is by reference, the variable’s lifetime ends when the
|
| 117 |
+
closure object’s lifetime ends.
|
| 118 |
+
|
| 119 |
+
[*Note 3*: This enables an *init-capture* like “`x = std::move(x)`”;
|
| 120 |
+
the second “`x`” must bind to a declaration in the surrounding
|
| 121 |
+
context. — *end note*]
|
| 122 |
+
|
| 123 |
+
[*Example 3*:
|
| 124 |
+
|
| 125 |
+
``` cpp
|
| 126 |
+
int x = 4;
|
| 127 |
+
auto y = [&r = x, x = x+1]()->int {
|
| 128 |
+
r += 2;
|
| 129 |
+
return x+2;
|
| 130 |
+
}(); // Updates ::x to 6, and initializes y to 7.
|
| 131 |
+
|
| 132 |
+
auto z = [a = 42](int a) { return 1; } // error: parameter and local variable have the same name
|
| 133 |
+
```
|
| 134 |
+
|
| 135 |
+
— *end example*]
|
| 136 |
+
|
| 137 |
+
A *lambda-expression* with an associated *capture-default* that does not
|
| 138 |
+
explicitly capture `*this` or a variable with automatic storage duration
|
| 139 |
+
(this excludes any *id-expression* that has been found to refer to an
|
| 140 |
+
*init-capture*'s associated non-static data member), is said to
|
| 141 |
+
*implicitly capture* the entity (i.e., `*this` or a variable) if the
|
| 142 |
+
*compound-statement*:
|
| 143 |
+
|
| 144 |
+
- odr-uses ([[basic.def.odr]]) the entity (in the case of a variable),
|
| 145 |
+
- odr-uses ([[basic.def.odr]]) `this` (in the case of the object
|
| 146 |
+
designated by `*this`), or
|
| 147 |
+
- names the entity in a potentially-evaluated expression (
|
| 148 |
+
[[basic.def.odr]]) where the enclosing full-expression depends on a
|
| 149 |
+
generic lambda parameter declared within the reaching scope of the
|
| 150 |
+
*lambda-expression*.
|
| 151 |
+
|
| 152 |
+
[*Example 4*:
|
| 153 |
+
|
| 154 |
+
``` cpp
|
| 155 |
+
void f(int, const int (&)[2] = {}) { } // #1
|
| 156 |
+
void f(const int&, const int (&)[1]) { } // #2
|
| 157 |
+
void test() {
|
| 158 |
+
const int x = 17;
|
| 159 |
+
auto g = [](auto a) {
|
| 160 |
+
f(x); // OK: calls #1, does not capture x
|
| 161 |
+
};
|
| 162 |
+
|
| 163 |
+
auto g2 = [=](auto a) {
|
| 164 |
+
int selector[sizeof(a) == 1 ? 1 : 2]{};
|
| 165 |
+
f(x, selector); // OK: is a dependent expression, so captures x
|
| 166 |
+
};
|
| 167 |
+
}
|
| 168 |
+
```
|
| 169 |
+
|
| 170 |
+
— *end example*]
|
| 171 |
+
|
| 172 |
+
All such implicitly captured entities shall be declared within the
|
| 173 |
+
reaching scope of the lambda expression.
|
| 174 |
+
|
| 175 |
+
[*Note 4*: The implicit capture of an entity by a nested
|
| 176 |
+
*lambda-expression* can cause its implicit capture by the containing
|
| 177 |
+
*lambda-expression* (see below). Implicit odr-uses of `this` can result
|
| 178 |
+
in implicit capture. — *end note*]
|
| 179 |
+
|
| 180 |
+
An entity is *captured* if it is captured explicitly or implicitly. An
|
| 181 |
+
entity captured by a *lambda-expression* is odr-used (
|
| 182 |
+
[[basic.def.odr]]) in the scope containing the *lambda-expression*. If
|
| 183 |
+
`*this` is captured by a local lambda expression, its nearest enclosing
|
| 184 |
+
function shall be a non-static member function. If a *lambda-expression*
|
| 185 |
+
or an instantiation of the function call operator template of a generic
|
| 186 |
+
lambda odr-uses ([[basic.def.odr]]) `this` or a variable with automatic
|
| 187 |
+
storage duration from its reaching scope, that entity shall be captured
|
| 188 |
+
by the *lambda-expression*. If a *lambda-expression* captures an entity
|
| 189 |
+
and that entity is not defined or captured in the immediately enclosing
|
| 190 |
+
lambda expression or function, the program is ill-formed.
|
| 191 |
+
|
| 192 |
+
[*Example 5*:
|
| 193 |
+
|
| 194 |
+
``` cpp
|
| 195 |
+
void f1(int i) {
|
| 196 |
+
int const N = 20;
|
| 197 |
+
auto m1 = [=]{
|
| 198 |
+
int const M = 30;
|
| 199 |
+
auto m2 = [i]{
|
| 200 |
+
int x[N][M]; // OK: N and M are not odr-used
|
| 201 |
+
x[0][0] = i; // OK: i is explicitly captured by m2 and implicitly captured by m1
|
| 202 |
+
};
|
| 203 |
+
};
|
| 204 |
+
struct s1 {
|
| 205 |
+
int f;
|
| 206 |
+
void work(int n) {
|
| 207 |
+
int m = n*n;
|
| 208 |
+
int j = 40;
|
| 209 |
+
auto m3 = [this,m] {
|
| 210 |
+
auto m4 = [&,j] { // error: j not captured by m3
|
| 211 |
+
int x = n; // error: n implicitly captured by m4 but not captured by m3
|
| 212 |
+
x += m; // OK: m implicitly captured by m4 and explicitly captured by m3
|
| 213 |
+
x += i; // error: i is outside of the reaching scope
|
| 214 |
+
x += f; // OK: this captured implicitly by m4 and explicitly by m3
|
| 215 |
+
};
|
| 216 |
+
};
|
| 217 |
+
}
|
| 218 |
+
};
|
| 219 |
+
}
|
| 220 |
+
|
| 221 |
+
struct s2 {
|
| 222 |
+
double ohseven = .007;
|
| 223 |
+
auto f() {
|
| 224 |
+
return [this] {
|
| 225 |
+
return [*this] {
|
| 226 |
+
return ohseven; // OK
|
| 227 |
+
}
|
| 228 |
+
}();
|
| 229 |
+
}
|
| 230 |
+
auto g() {
|
| 231 |
+
return [] {
|
| 232 |
+
return [*this] { }; // error: *this not captured by outer lambda-expression
|
| 233 |
+
}();
|
| 234 |
+
}
|
| 235 |
+
};
|
| 236 |
+
```
|
| 237 |
+
|
| 238 |
+
— *end example*]
|
| 239 |
+
|
| 240 |
+
A *lambda-expression* appearing in a default argument shall not
|
| 241 |
+
implicitly or explicitly capture any entity.
|
| 242 |
+
|
| 243 |
+
[*Example 6*:
|
| 244 |
+
|
| 245 |
+
``` cpp
|
| 246 |
+
void f2() {
|
| 247 |
+
int i = 1;
|
| 248 |
+
void g1(int = ([i]{ return i; })()); // ill-formed
|
| 249 |
+
void g2(int = ([i]{ return 0; })()); // ill-formed
|
| 250 |
+
void g3(int = ([=]{ return i; })()); // ill-formed
|
| 251 |
+
void g4(int = ([=]{ return 0; })()); // OK
|
| 252 |
+
void g5(int = ([]{ return sizeof i; })()); // OK
|
| 253 |
+
}
|
| 254 |
+
```
|
| 255 |
+
|
| 256 |
+
— *end example*]
|
| 257 |
+
|
| 258 |
+
An entity is *captured by copy* if
|
| 259 |
+
|
| 260 |
+
- it is implicitly captured, the *capture-default* is `=`, and the
|
| 261 |
+
captured entity is not `*this`, or
|
| 262 |
+
- it is explicitly captured with a capture that is not of the form
|
| 263 |
+
`this`, `&` *identifier*, or `&` *identifier* *initializer*.
|
| 264 |
+
|
| 265 |
+
For each entity captured by copy, an unnamed non-static data member is
|
| 266 |
+
declared in the closure type. The declaration order of these members is
|
| 267 |
+
unspecified. The type of such a data member is the referenced type if
|
| 268 |
+
the entity is a reference to an object, an lvalue reference to the
|
| 269 |
+
referenced function type if the entity is a reference to a function, or
|
| 270 |
+
the type of the corresponding captured entity otherwise. A member of an
|
| 271 |
+
anonymous union shall not be captured by copy.
|
| 272 |
+
|
| 273 |
+
Every *id-expression* within the *compound-statement* of a
|
| 274 |
+
*lambda-expression* that is an odr-use ([[basic.def.odr]]) of an entity
|
| 275 |
+
captured by copy is transformed into an access to the corresponding
|
| 276 |
+
unnamed data member of the closure type.
|
| 277 |
+
|
| 278 |
+
[*Note 5*: An *id-expression* that is not an odr-use refers to the
|
| 279 |
+
original entity, never to a member of the closure type. Furthermore,
|
| 280 |
+
such an *id-expression* does not cause the implicit capture of the
|
| 281 |
+
entity. — *end note*]
|
| 282 |
+
|
| 283 |
+
If `*this` is captured by copy, each odr-use of `this` is transformed
|
| 284 |
+
into a pointer to the corresponding unnamed data member of the closure
|
| 285 |
+
type, cast ([[expr.cast]]) to the type of `this`.
|
| 286 |
+
|
| 287 |
+
[*Note 6*: The cast ensures that the transformed expression is a
|
| 288 |
+
prvalue. — *end note*]
|
| 289 |
+
|
| 290 |
+
An *id-expression* within the *compound-statement* of a
|
| 291 |
+
*lambda-expression* that is an odr-use of a reference captured by
|
| 292 |
+
reference refers to the entity to which the captured reference is bound
|
| 293 |
+
and not to the captured reference.
|
| 294 |
+
|
| 295 |
+
[*Note 7*: The validity of such captures is determined by the lifetime
|
| 296 |
+
of the object to which the reference refers, not by the lifetime of the
|
| 297 |
+
reference itself. — *end note*]
|
| 298 |
+
|
| 299 |
+
[*Example 7*:
|
| 300 |
+
|
| 301 |
+
``` cpp
|
| 302 |
+
void f(const int*);
|
| 303 |
+
void g() {
|
| 304 |
+
const int N = 10;
|
| 305 |
+
[=] {
|
| 306 |
+
int arr[N]; // OK: not an odr-use, refers to automatic variable
|
| 307 |
+
f(&N); // OK: causes N to be captured; &N points to
|
| 308 |
+
// the corresponding member of the closure type
|
| 309 |
+
};
|
| 310 |
+
}
|
| 311 |
+
auto h(int &r) {
|
| 312 |
+
return [&] {
|
| 313 |
+
++r; // Valid after h returns if the lifetime of the
|
| 314 |
+
// object to which r is bound has not ended
|
| 315 |
+
};
|
| 316 |
+
}
|
| 317 |
+
```
|
| 318 |
+
|
| 319 |
+
— *end example*]
|
| 320 |
+
|
| 321 |
+
An entity is *captured by reference* if it is implicitly or explicitly
|
| 322 |
+
captured but not captured by copy. It is unspecified whether additional
|
| 323 |
+
unnamed non-static data members are declared in the closure type for
|
| 324 |
+
entities captured by reference. If declared, such non-static data
|
| 325 |
+
members shall be of literal type.
|
| 326 |
+
|
| 327 |
+
[*Example 8*:
|
| 328 |
+
|
| 329 |
+
``` cpp
|
| 330 |
+
// The inner closure type must be a literal type regardless of how reference captures are represented.
|
| 331 |
+
static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4);
|
| 332 |
+
```
|
| 333 |
+
|
| 334 |
+
— *end example*]
|
| 335 |
+
|
| 336 |
+
A bit-field or a member of an anonymous union shall not be captured by
|
| 337 |
+
reference.
|
| 338 |
+
|
| 339 |
+
If a *lambda-expression* `m2` captures an entity and that entity is
|
| 340 |
+
captured by an immediately enclosing *lambda-expression* `m1`, then
|
| 341 |
+
`m2`’s capture is transformed as follows:
|
| 342 |
+
|
| 343 |
+
- if `m1` captures the entity by copy, `m2` captures the corresponding
|
| 344 |
+
non-static data member of `m1`’s closure type;
|
| 345 |
+
- if `m1` captures the entity by reference, `m2` captures the same
|
| 346 |
+
entity captured by `m1`.
|
| 347 |
+
|
| 348 |
+
[*Example 9*:
|
| 349 |
+
|
| 350 |
+
The nested lambda expressions and invocations below will output
|
| 351 |
+
`123234`.
|
| 352 |
+
|
| 353 |
+
``` cpp
|
| 354 |
+
int a = 1, b = 1, c = 1;
|
| 355 |
+
auto m1 = [a, &b, &c]() mutable {
|
| 356 |
+
auto m2 = [a, b, &c]() mutable {
|
| 357 |
+
std::cout << a << b << c;
|
| 358 |
+
a = 4; b = 4; c = 4;
|
| 359 |
+
};
|
| 360 |
+
a = 3; b = 3; c = 3;
|
| 361 |
+
m2();
|
| 362 |
+
};
|
| 363 |
+
a = 2; b = 2; c = 2;
|
| 364 |
+
m1();
|
| 365 |
+
std::cout << a << b << c;
|
| 366 |
+
```
|
| 367 |
+
|
| 368 |
+
— *end example*]
|
| 369 |
+
|
| 370 |
+
Every occurrence of `decltype((x))` where `x` is a possibly
|
| 371 |
+
parenthesized *id-expression* that names an entity of automatic storage
|
| 372 |
+
duration is treated as if `x` were transformed into an access to a
|
| 373 |
+
corresponding data member of the closure type that would have been
|
| 374 |
+
declared if `x` were an odr-use of the denoted entity.
|
| 375 |
+
|
| 376 |
+
[*Example 10*:
|
| 377 |
+
|
| 378 |
+
``` cpp
|
| 379 |
+
void f3() {
|
| 380 |
+
float x, &r = x;
|
| 381 |
+
[=] { // x and r are not captured (appearance in a decltype operand is not an odr-use)
|
| 382 |
+
decltype(x) y1; // y1 has type float
|
| 383 |
+
decltype((x)) y2 = y1; // y2 has type float const& because this lambda is not mutable and x is an lvalue
|
| 384 |
+
decltype(r) r1 = y1; // r1 has type float& (transformation not considered)
|
| 385 |
+
decltype((r)) r2 = y2; // r2 has type float const&
|
| 386 |
+
};
|
| 387 |
+
}
|
| 388 |
+
```
|
| 389 |
+
|
| 390 |
+
— *end example*]
|
| 391 |
+
|
| 392 |
+
When the *lambda-expression* is evaluated, the entities that are
|
| 393 |
+
captured by copy are used to direct-initialize each corresponding
|
| 394 |
+
non-static data member of the resulting closure object, and the
|
| 395 |
+
non-static data members corresponding to the *init-capture*s are
|
| 396 |
+
initialized as indicated by the corresponding *initializer* (which may
|
| 397 |
+
be copy- or direct-initialization). (For array members, the array
|
| 398 |
+
elements are direct-initialized in increasing subscript order.) These
|
| 399 |
+
initializations are performed in the (unspecified) order in which the
|
| 400 |
+
non-static data members are declared.
|
| 401 |
+
|
| 402 |
+
[*Note 8*: This ensures that the destructions will occur in the reverse
|
| 403 |
+
order of the constructions. — *end note*]
|
| 404 |
+
|
| 405 |
+
[*Note 9*: If a non-reference entity is implicitly or explicitly
|
| 406 |
+
captured by reference, invoking the function call operator of the
|
| 407 |
+
corresponding *lambda-expression* after the lifetime of the entity has
|
| 408 |
+
ended is likely to result in undefined behavior. — *end note*]
|
| 409 |
+
|
| 410 |
+
A *simple-capture* followed by an ellipsis is a pack expansion (
|
| 411 |
+
[[temp.variadic]]). An *init-capture* followed by an ellipsis is
|
| 412 |
+
ill-formed.
|
| 413 |
+
|
| 414 |
+
[*Example 11*:
|
| 415 |
+
|
| 416 |
+
``` cpp
|
| 417 |
+
template<class... Args>
|
| 418 |
+
void f(Args... args) {
|
| 419 |
+
auto lm = [&, args...] { return g(args...); };
|
| 420 |
+
lm();
|
| 421 |
+
}
|
| 422 |
+
```
|
| 423 |
+
|
| 424 |
+
— *end example*]
|
| 425 |
+
|