- tmp/tmp8vm58ccx/{from.md → to.md} +606 -272
tmp/tmp8vm58ccx/{from.md → to.md}
RENAMED
|
@@ -1,77 +1,75 @@
|
|
| 1 |
## Primary expressions <a id="expr.prim">[[expr.prim]]</a>
|
| 2 |
|
| 3 |
-
### General <a id="expr.prim.general">[[expr.prim.general]]</a>
|
| 4 |
-
|
| 5 |
``` bnf
|
| 6 |
primary-expression:
|
| 7 |
literal
|
| 8 |
'this'
|
| 9 |
'(' expression ')'
|
| 10 |
id-expression
|
| 11 |
lambda-expression
|
|
|
|
| 12 |
```
|
| 13 |
|
| 14 |
-
|
| 15 |
-
id-expression:
|
| 16 |
-
unqualified-id
|
| 17 |
-
qualified-id
|
| 18 |
-
```
|
| 19 |
-
|
| 20 |
-
``` bnf
|
| 21 |
-
unqualified-id:
|
| 22 |
-
identifier
|
| 23 |
-
operator-function-id
|
| 24 |
-
conversion-function-id
|
| 25 |
-
literal-operator-id
|
| 26 |
-
'~' class-name
|
| 27 |
-
'~' decltype-specifier
|
| 28 |
-
template-id
|
| 29 |
-
```
|
| 30 |
|
| 31 |
A *literal* is a primary expression. Its type depends on its form (
|
| 32 |
[[lex.literal]]). A string literal is an lvalue; all other literals are
|
| 33 |
prvalues.
|
| 34 |
|
|
|
|
|
|
|
| 35 |
The keyword `this` names a pointer to the object for which a non-static
|
| 36 |
member function ([[class.this]]) is invoked or a non-static data
|
| 37 |
member’s initializer ([[class.mem]]) is evaluated.
|
| 38 |
|
| 39 |
If a declaration declares a member function or member function template
|
| 40 |
of a class `X`, the expression `this` is a prvalue of type “pointer to
|
| 41 |
-
*cv-qualifier-seq* `X`” between the optional *cv-
|
| 42 |
end of the *function-definition*, *member-declarator*, or *declarator*.
|
| 43 |
It shall not appear before the optional *cv-qualifier-seq* and it shall
|
| 44 |
not appear within the declaration of a static member function (although
|
| 45 |
its type and value category are defined within a static member function
|
| 46 |
-
as they are within a non-static member function).
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
|
| 53 |
``` cpp
|
| 54 |
struct A {
|
| 55 |
char g();
|
| 56 |
template<class T> auto f(T t) -> decltype(t + g())
|
| 57 |
{ return t + g(); }
|
| 58 |
};
|
| 59 |
template auto A::f(int t) -> decltype(t + g());
|
| 60 |
```
|
| 61 |
|
|
|
|
|
|
|
| 62 |
Otherwise, if a *member-declarator* declares a non-static data member (
|
| 63 |
[[class.mem]]) of a class `X`, the expression `this` is a prvalue of
|
| 64 |
-
type “pointer to `X`” within the optional
|
| 65 |
-
It shall not appear elsewhere in the
|
|
|
|
| 66 |
|
| 67 |
The expression `this` shall not appear in any other context.
|
| 68 |
|
|
|
|
|
|
|
| 69 |
``` cpp
|
| 70 |
class Outer {
|
| 71 |
int a[sizeof(*this)]; // error: not inside a member function
|
| 72 |
-
unsigned int sz = sizeof(*this); // OK: in
|
| 73 |
|
| 74 |
void f() {
|
| 75 |
int b[sizeof(*this)]; // OK
|
| 76 |
|
| 77 |
struct Inner {
|
|
@@ -79,32 +77,85 @@ class Outer {
|
|
| 79 |
};
|
| 80 |
}
|
| 81 |
};
|
| 82 |
```
|
| 83 |
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
|
|
|
|
|
|
|
|
|
| 87 |
parenthesized expression can be used in exactly the same contexts as
|
| 88 |
-
those where
|
| 89 |
-
|
| 90 |
|
| 91 |
-
|
| 92 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
|
| 94 |
An *identifier* is an *id-expression* provided it has been suitably
|
| 95 |
-
declared (Clause [[dcl.dcl]]).
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
see [[
|
| 99 |
-
|
| 100 |
-
|
|
|
|
|
|
|
| 101 |
member is transformed to a class member access expression (
|
| 102 |
-
[[class.mfct.non-static]]).
|
| 103 |
-
|
| 104 |
-
The
|
| 105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
|
| 107 |
``` bnf
|
| 108 |
qualified-id:
|
| 109 |
nested-name-specifier 'template'ₒₚₜ unqualified-id
|
| 110 |
```
|
|
@@ -125,29 +176,36 @@ shall be a class or enumeration type.
|
|
| 125 |
A *nested-name-specifier* that denotes a class, optionally followed by
|
| 126 |
the keyword `template` ([[temp.names]]), and then followed by the name
|
| 127 |
of a member of either that class ([[class.mem]]) or one of its base
|
| 128 |
classes (Clause [[class.derived]]), is a *qualified-id*;
|
| 129 |
[[class.qual]] describes name lookup for class members that appear in
|
| 130 |
-
*qualified-
|
| 131 |
type of the member. The result is an lvalue if the member is a static
|
| 132 |
-
member function or a data member and a prvalue otherwise.
|
| 133 |
-
can be referred to using a *qualified-id* at any point in its potential
|
| 134 |
-
scope ([[basic.scope.class]]). Where *class-name* `::~` *class-name* is
|
| 135 |
-
used, the two *class-name*s shall refer to the same class; this notation
|
| 136 |
-
names the destructor ([[class.dtor]]). The form
|
| 137 |
-
`~` *decltype-specifier* also denotes the destructor, but it shall not
|
| 138 |
-
be used as the *unqualified-id* in a *qualified-id*. a *typedef-name*
|
| 139 |
-
that names a class is a *class-name* ([[class.name]]).
|
| 140 |
|
| 141 |
-
|
| 142 |
-
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
name
|
| 146 |
-
|
| 147 |
-
The
|
| 148 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
|
| 150 |
A *nested-name-specifier* that denotes an enumeration ([[dcl.enum]]),
|
| 151 |
followed by the name of an enumerator of that enumeration, is a
|
| 152 |
*qualified-id* that refers to the enumerator. The result is the
|
| 153 |
enumerator. The type of the result is the type of the enumeration. The
|
|
@@ -156,141 +214,104 @@ result is a prvalue.
|
|
| 156 |
In a *qualified-id*, if the *unqualified-id* is a
|
| 157 |
*conversion-function-id*, its *conversion-type-id* shall denote the same
|
| 158 |
type in both the context in which the entire *qualified-id* occurs and
|
| 159 |
in the context of the class denoted by the *nested-name-specifier*.
|
| 160 |
|
| 161 |
-
An *id-expression* that denotes a non-static data member or non-static
|
| 162 |
-
member function of a class can only be used:
|
| 163 |
-
|
| 164 |
-
- as part of a class member access ([[expr.ref]]) in which the object
|
| 165 |
-
expression refers to the member’s class[^4] or a class derived from
|
| 166 |
-
that class, or
|
| 167 |
-
- to form a pointer to member ([[expr.unary.op]]), or
|
| 168 |
-
- if that *id-expression* denotes a non-static data member and it
|
| 169 |
-
appears in an unevaluated operand.
|
| 170 |
-
``` cpp
|
| 171 |
-
struct S {
|
| 172 |
-
int m;
|
| 173 |
-
};
|
| 174 |
-
int i = sizeof(S::m); // OK
|
| 175 |
-
int j = sizeof(S::m + 42); // OK
|
| 176 |
-
```
|
| 177 |
-
|
| 178 |
### Lambda expressions <a id="expr.prim.lambda">[[expr.prim.lambda]]</a>
|
| 179 |
|
| 180 |
-
Lambda expressions provide a concise way to create simple function
|
| 181 |
-
objects.
|
| 182 |
-
|
| 183 |
-
``` cpp
|
| 184 |
-
#include <algorithm>
|
| 185 |
-
#include <cmath>
|
| 186 |
-
void abssort(float* x, unsigned N) {
|
| 187 |
-
std::sort(x, x + N,
|
| 188 |
-
[](float a, float b) {
|
| 189 |
-
return std::abs(a) < std::abs(b);
|
| 190 |
-
});
|
| 191 |
-
}
|
| 192 |
-
```
|
| 193 |
-
|
| 194 |
``` bnf
|
| 195 |
lambda-expression:
|
| 196 |
lambda-introducer lambda-declaratorₒₚₜ compound-statement
|
| 197 |
```
|
| 198 |
|
| 199 |
``` bnf
|
| 200 |
lambda-introducer:
|
| 201 |
'[' lambda-captureₒₚₜ ']'
|
| 202 |
```
|
| 203 |
|
| 204 |
-
``` bnf
|
| 205 |
-
lambda-capture:
|
| 206 |
-
capture-default
|
| 207 |
-
capture-list
|
| 208 |
-
capture-default ',' capture-list
|
| 209 |
-
```
|
| 210 |
-
|
| 211 |
-
``` bnf
|
| 212 |
-
capture-default:
|
| 213 |
-
'&'
|
| 214 |
-
'='
|
| 215 |
-
```
|
| 216 |
-
|
| 217 |
-
``` bnf
|
| 218 |
-
capture-list:
|
| 219 |
-
capture '...'ₒₚₜ
|
| 220 |
-
capture-list ',' capture '...'ₒₚₜ
|
| 221 |
-
```
|
| 222 |
-
|
| 223 |
-
``` bnf
|
| 224 |
-
capture:
|
| 225 |
-
simple-capture
|
| 226 |
-
init-capture
|
| 227 |
-
```
|
| 228 |
-
|
| 229 |
-
``` bnf
|
| 230 |
-
simple-capture:
|
| 231 |
-
identifier
|
| 232 |
-
'&' identifier
|
| 233 |
-
'this'
|
| 234 |
-
```
|
| 235 |
-
|
| 236 |
-
``` bnf
|
| 237 |
-
init-capture:
|
| 238 |
-
identifier initializer
|
| 239 |
-
'&' identifier initializer
|
| 240 |
-
```
|
| 241 |
-
|
| 242 |
``` bnf
|
| 243 |
lambda-declarator:
|
| 244 |
-
'(' parameter-declaration-clause ')'
|
| 245 |
-
|
| 246 |
```
|
| 247 |
|
| 248 |
-
|
| 249 |
-
|
| 250 |
-
|
| 251 |
-
[
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
| 263 |
-
*lambda-expression*
|
| 264 |
-
|
| 265 |
-
|
| 266 |
-
|
| 267 |
-
|
| 268 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 269 |
|
| 270 |
- the size and/or alignment of the closure type,
|
| 271 |
- whether the closure type is trivially copyable (Clause [[class]]),
|
| 272 |
- whether the closure type is a standard-layout class (Clause
|
| 273 |
[[class]]), or
|
| 274 |
- whether the closure type is a POD class (Clause [[class]]).
|
| 275 |
|
| 276 |
An implementation shall not add members of rvalue reference type to the
|
| 277 |
closure type.
|
| 278 |
|
| 279 |
-
If a *lambda-expression* does not include a *lambda-declarator*, it is
|
| 280 |
-
as if the *lambda-declarator* were `()`. The lambda return type is
|
| 281 |
-
`auto`, which is replaced by the *trailing-return-type* if provided
|
| 282 |
-
and/or deduced from `return` statements as described in
|
| 283 |
-
[[dcl.spec.auto]].
|
| 284 |
-
|
| 285 |
-
``` cpp
|
| 286 |
-
auto x1 = [](int i){ return i; }; // OK: return type is int
|
| 287 |
-
auto x2 = []{ return { 1, 2 }; }; // error: deducing return type from braced-init-list
|
| 288 |
-
int j;
|
| 289 |
-
auto x3 = []()->auto&& { return j; }; // OK: return type is int&
|
| 290 |
-
```
|
| 291 |
-
|
| 292 |
The closure type for a non-generic *lambda-expression* has a public
|
| 293 |
inline function call operator ([[over.call]]) whose parameters and
|
| 294 |
return type are described by the *lambda-expression*’s
|
| 295 |
*parameter-declaration-clause* and *trailing-return-type* respectively.
|
| 296 |
For a generic lambda, the closure type has a public inline function call
|
|
@@ -304,13 +325,16 @@ of the function call operator template are derived from the
|
|
| 304 |
*lambda-expression*'s *trailing-return-type* and
|
| 305 |
*parameter-declaration-clause* by replacing each occurrence of `auto` in
|
| 306 |
the *decl-specifier*s of the *parameter-declaration-clause* with the
|
| 307 |
name of the corresponding invented *template-parameter*.
|
| 308 |
|
|
|
|
|
|
|
| 309 |
``` cpp
|
| 310 |
auto glambda = [](auto a, auto&& b) { return a < b; };
|
| 311 |
bool b = glambda(3, 3.14); // OK
|
|
|
|
| 312 |
auto vglambda = [](auto printer) {
|
| 313 |
return [=](auto&& ... ts) { // OK: ts is a function parameter pack
|
| 314 |
printer(std::forward<decltype(ts)>(ts)...);
|
| 315 |
|
| 316 |
return [=]() {
|
|
@@ -322,42 +346,99 @@ auto glambda = [](auto a, auto&& b) { return a < b; };
|
|
| 322 |
{ std::cout << v1 << v2 << v3; } );
|
| 323 |
auto q = p(1, 'a', 3.14); // OK: outputs 1a3.14
|
| 324 |
q(); // OK: outputs 1a3.14
|
| 325 |
```
|
| 326 |
|
| 327 |
-
|
|
|
|
|
|
|
| 328 |
[[class.mfct.non-static]]) if and only if the *lambda-expression*’s
|
| 329 |
*parameter-declaration-clause* is not followed by `mutable`. It is
|
| 330 |
-
neither virtual nor declared `volatile`. Any *
|
| 331 |
specified on a *lambda-expression* applies to the corresponding function
|
| 332 |
call operator or operator template. An *attribute-specifier-seq* in a
|
| 333 |
*lambda-declarator* appertains to the type of the corresponding function
|
| 334 |
-
call operator or operator template.
|
| 335 |
-
|
| 336 |
-
*lambda-expression*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 337 |
|
| 338 |
The closure type for a non-generic *lambda-expression* with no
|
| 339 |
-
*lambda-capture* has a
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
|
|
|
|
|
|
|
| 348 |
*template-parameter-list*, and the pointer to function has the same
|
| 349 |
parameter types, as the function call operator template. The return type
|
| 350 |
of the pointer to function shall behave as if it were a
|
| 351 |
*decltype-specifier* denoting the return type of the corresponding
|
| 352 |
-
function call operator template specialization.
|
| 353 |
-
|
| 354 |
-
|
| 355 |
-
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 359 |
|
| 360 |
``` cpp
|
| 361 |
auto glambda = [](auto a) { return a; };
|
| 362 |
int (*fp)(int) = glambda;
|
| 363 |
```
|
|
@@ -379,10 +460,14 @@ struct Closure {
|
|
| 379 |
template<class T> operator fptr_t<T>() const
|
| 380 |
{ return &lambda_call_operator_invoker; }
|
| 381 |
};
|
| 382 |
```
|
| 383 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 384 |
``` cpp
|
| 385 |
void f1(int (*)(int)) { }
|
| 386 |
void f2(char (*)(int)) { }
|
| 387 |
|
| 388 |
void g(int (*)(int)) { } // #1
|
|
@@ -397,33 +482,63 @@ f2(glambda); // error: ID is not convertible
|
|
| 397 |
g(glambda); // error: ambiguous
|
| 398 |
h(glambda); // OK: calls #3 since it is convertible from ID
|
| 399 |
int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
|
| 400 |
```
|
| 401 |
|
|
|
|
|
|
|
| 402 |
The value returned by any given specialization of this conversion
|
| 403 |
-
function template
|
| 404 |
has the same effect as invoking the generic lambda’s corresponding
|
| 405 |
-
function call operator template specialization.
|
| 406 |
-
|
| 407 |
-
|
| 408 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 409 |
|
| 410 |
``` cpp
|
| 411 |
auto GL = [](auto a) { std::cout << a; return a; };
|
| 412 |
int (*GL_int)(int) = GL; // OK: through conversion function template
|
| 413 |
GL_int(3); // OK: same as GL(3)
|
| 414 |
```
|
| 415 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 416 |
The *lambda-expression*’s *compound-statement* yields the
|
| 417 |
*function-body* ([[dcl.fct.def]]) of the function call operator, but
|
| 418 |
for purposes of name lookup ([[basic.lookup]]), determining the type
|
| 419 |
and value of `this` ([[class.this]]) and transforming *id-expression*s
|
| 420 |
referring to non-static class members into class member access
|
| 421 |
expressions using `(*this)` ([[class.mfct.non-static]]), the
|
| 422 |
*compound-statement* is considered in the context of the
|
| 423 |
*lambda-expression*.
|
| 424 |
|
|
|
|
|
|
|
| 425 |
``` cpp
|
| 426 |
struct S1 {
|
| 427 |
int x, y;
|
| 428 |
int operator()(int);
|
| 429 |
void f() {
|
|
@@ -433,46 +548,135 @@ struct S1 {
|
|
| 433 |
};
|
| 434 |
}
|
| 435 |
};
|
| 436 |
```
|
| 437 |
|
|
|
|
|
|
|
| 438 |
Further, a variable `__func__` is implicitly defined at the beginning of
|
| 439 |
the *compound-statement* of the *lambda-expression*, with semantics as
|
| 440 |
described in [[dcl.fct.def.general]].
|
| 441 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 442 |
If a *lambda-capture* includes a *capture-default* that is `&`, no
|
| 443 |
identifier in a *simple-capture* of that *lambda-capture* shall be
|
| 444 |
preceded by `&`. If a *lambda-capture* includes a *capture-default* that
|
| 445 |
is `=`, each *simple-capture* of that *lambda-capture* shall be of the
|
| 446 |
-
form “`&` *identifier*”
|
| 447 |
-
|
| 448 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 449 |
|
| 450 |
``` cpp
|
| 451 |
struct S2 { void f(int i); };
|
| 452 |
void S2::f(int i) {
|
| 453 |
[&, i]{ }; // OK
|
| 454 |
[&, &i]{ }; // error: i preceded by & when & is the default
|
|
|
|
| 455 |
[=, this]{ }; // error: this when = is the default
|
| 456 |
[i, i]{ }; // error: i repeated
|
|
|
|
| 457 |
}
|
| 458 |
```
|
| 459 |
|
|
|
|
|
|
|
| 460 |
A *lambda-expression* whose smallest enclosing scope is a block scope (
|
| 461 |
[[basic.scope.block]]) is a *local lambda expression*; any other
|
| 462 |
*lambda-expression* shall not have a *capture-default* or
|
| 463 |
*simple-capture* in its *lambda-introducer*. The *reaching scope* of a
|
| 464 |
local lambda expression is the set of enclosing scopes up to and
|
| 465 |
-
including the innermost enclosing function and its parameters.
|
| 466 |
-
|
|
|
|
|
|
|
| 467 |
|
| 468 |
The *identifier* in a *simple-capture* is looked up using the usual
|
| 469 |
rules for unqualified name lookup ([[basic.lookup.unqual]]); each such
|
| 470 |
lookup shall find an entity. An entity that is designated by a
|
| 471 |
*simple-capture* is said to be *explicitly captured*, and shall be
|
| 472 |
-
`this`
|
| 473 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 474 |
|
| 475 |
An *init-capture* behaves as if it declares and explicitly captures a
|
| 476 |
variable of the form “`auto` *init-capture* `;`” whose declarative
|
| 477 |
region is the *lambda-expression*’s *compound-statement*, except that:
|
| 478 |
|
|
@@ -482,34 +686,45 @@ region is the *lambda-expression*’s *compound-statement*, except that:
|
|
| 482 |
non-static data member, and no additional copy and destruction is
|
| 483 |
performed, and
|
| 484 |
- if the capture is by reference, the variable’s lifetime ends when the
|
| 485 |
closure object’s lifetime ends.
|
| 486 |
|
| 487 |
-
This enables an *init-capture* like “`x = std::move(x)`”;
|
| 488 |
-
“`x`” must bind to a declaration in the surrounding
|
|
|
|
|
|
|
|
|
|
| 489 |
|
| 490 |
``` cpp
|
| 491 |
int x = 4;
|
| 492 |
auto y = [&r = x, x = x+1]()->int {
|
| 493 |
r += 2;
|
| 494 |
return x+2;
|
| 495 |
}(); // Updates ::x to 6, and initializes y to 7.
|
|
|
|
|
|
|
| 496 |
```
|
| 497 |
|
|
|
|
|
|
|
| 498 |
A *lambda-expression* with an associated *capture-default* that does not
|
| 499 |
-
explicitly capture `this` or a variable with automatic storage duration
|
| 500 |
(this excludes any *id-expression* that has been found to refer to an
|
| 501 |
*init-capture*'s associated non-static data member), is said to
|
| 502 |
-
*implicitly capture* the entity (i.e., `this` or a variable) if the
|
| 503 |
*compound-statement*:
|
| 504 |
|
| 505 |
-
- odr-uses ([[basic.def.odr]]) the entity
|
|
|
|
|
|
|
| 506 |
- names the entity in a potentially-evaluated expression (
|
| 507 |
[[basic.def.odr]]) where the enclosing full-expression depends on a
|
| 508 |
generic lambda parameter declared within the reaching scope of the
|
| 509 |
*lambda-expression*.
|
| 510 |
|
|
|
|
|
|
|
| 511 |
``` cpp
|
| 512 |
void f(int, const int (&)[2] = {}) { } // #1
|
| 513 |
void f(const int&, const int (&)[1]) { } // #2
|
| 514 |
void test() {
|
| 515 |
const int x = 17;
|
|
@@ -522,63 +737,85 @@ void test() {
|
|
| 522 |
f(x, selector); // OK: is a dependent expression, so captures x
|
| 523 |
};
|
| 524 |
}
|
| 525 |
```
|
| 526 |
|
|
|
|
|
|
|
| 527 |
All such implicitly captured entities shall be declared within the
|
| 528 |
-
reaching scope of the lambda expression.
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
|
|
|
|
|
|
| 532 |
|
| 533 |
An entity is *captured* if it is captured explicitly or implicitly. An
|
| 534 |
entity captured by a *lambda-expression* is odr-used (
|
| 535 |
[[basic.def.odr]]) in the scope containing the *lambda-expression*. If
|
| 536 |
-
`this` is captured by a local lambda expression, its nearest enclosing
|
| 537 |
function shall be a non-static member function. If a *lambda-expression*
|
| 538 |
or an instantiation of the function call operator template of a generic
|
| 539 |
lambda odr-uses ([[basic.def.odr]]) `this` or a variable with automatic
|
| 540 |
storage duration from its reaching scope, that entity shall be captured
|
| 541 |
by the *lambda-expression*. If a *lambda-expression* captures an entity
|
| 542 |
and that entity is not defined or captured in the immediately enclosing
|
| 543 |
lambda expression or function, the program is ill-formed.
|
| 544 |
|
|
|
|
|
|
|
| 545 |
``` cpp
|
| 546 |
void f1(int i) {
|
| 547 |
int const N = 20;
|
| 548 |
auto m1 = [=]{
|
| 549 |
int const M = 30;
|
| 550 |
auto m2 = [i]{
|
| 551 |
int x[N][M]; // OK: N and M are not odr-used
|
| 552 |
-
x[0][0] = i; // OK: i is explicitly captured by m2
|
| 553 |
-
// and implicitly captured by m1
|
| 554 |
};
|
| 555 |
};
|
| 556 |
struct s1 {
|
| 557 |
int f;
|
| 558 |
void work(int n) {
|
| 559 |
int m = n*n;
|
| 560 |
int j = 40;
|
| 561 |
auto m3 = [this,m] {
|
| 562 |
auto m4 = [&,j] { // error: j not captured by m3
|
| 563 |
-
int x = n; // error: n implicitly captured by m4
|
| 564 |
-
|
| 565 |
-
x += m; // OK: m implicitly captured by m4
|
| 566 |
-
// and explicitly captured by m3
|
| 567 |
x += i; // error: i is outside of the reaching scope
|
| 568 |
-
x += f; // OK: this captured implicitly by m4
|
| 569 |
-
// and explicitly by m3
|
| 570 |
};
|
| 571 |
};
|
| 572 |
}
|
| 573 |
};
|
| 574 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 575 |
```
|
| 576 |
|
|
|
|
|
|
|
| 577 |
A *lambda-expression* appearing in a default argument shall not
|
| 578 |
implicitly or explicitly capture any entity.
|
| 579 |
|
|
|
|
|
|
|
| 580 |
``` cpp
|
| 581 |
void f2() {
|
| 582 |
int i = 1;
|
| 583 |
void g1(int = ([i]{ return i; })()); // ill-formed
|
| 584 |
void g2(int = ([i]{ return 0; })()); // ill-formed
|
|
@@ -586,38 +823,105 @@ void f2() {
|
|
| 586 |
void g4(int = ([=]{ return 0; })()); // OK
|
| 587 |
void g5(int = ([]{ return sizeof i; })()); // OK
|
| 588 |
}
|
| 589 |
```
|
| 590 |
|
| 591 |
-
|
| 592 |
-
|
| 593 |
-
|
| 594 |
-
|
| 595 |
-
|
| 596 |
-
|
| 597 |
-
|
| 598 |
-
|
| 599 |
-
|
| 600 |
-
|
| 601 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 602 |
|
| 603 |
An entity is *captured by reference* if it is implicitly or explicitly
|
| 604 |
captured but not captured by copy. It is unspecified whether additional
|
| 605 |
unnamed non-static data members are declared in the closure type for
|
| 606 |
-
entities captured by reference.
|
| 607 |
-
be
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 608 |
|
| 609 |
If a *lambda-expression* `m2` captures an entity and that entity is
|
| 610 |
captured by an immediately enclosing *lambda-expression* `m1`, then
|
| 611 |
`m2`’s capture is transformed as follows:
|
| 612 |
|
| 613 |
- if `m1` captures the entity by copy, `m2` captures the corresponding
|
| 614 |
non-static data member of `m1`’s closure type;
|
| 615 |
- if `m1` captures the entity by reference, `m2` captures the same
|
| 616 |
entity captured by `m1`.
|
| 617 |
|
| 618 |
-
|
|
|
|
|
|
|
| 619 |
`123234`.
|
| 620 |
|
| 621 |
``` cpp
|
| 622 |
int a = 1, b = 1, c = 1;
|
| 623 |
auto m1 = [a, &b, &c]() mutable {
|
|
@@ -631,86 +935,116 @@ auto m1 = [a, &b, &c]() mutable {
|
|
| 631 |
a = 2; b = 2; c = 2;
|
| 632 |
m1();
|
| 633 |
std::cout << a << b << c;
|
| 634 |
```
|
| 635 |
|
| 636 |
-
|
| 637 |
-
*lambda-expression* that is an odr-use ([[basic.def.odr]]) of an entity
|
| 638 |
-
captured by copy is transformed into an access to the corresponding
|
| 639 |
-
unnamed data member of the closure type. An *id-expression* that is not
|
| 640 |
-
an odr-use refers to the original entity, never to a member of the
|
| 641 |
-
closure type. Furthermore, such an *id-expression* does not cause the
|
| 642 |
-
implicit capture of the entity. If `this` is captured, each odr-use of
|
| 643 |
-
`this` is transformed into an access to the corresponding unnamed data
|
| 644 |
-
member of the closure type, cast ([[expr.cast]]) to the type of `this`.
|
| 645 |
-
The cast ensures that the transformed expression is a prvalue.
|
| 646 |
-
|
| 647 |
-
``` cpp
|
| 648 |
-
void f(const int*);
|
| 649 |
-
void g() {
|
| 650 |
-
const int N = 10;
|
| 651 |
-
[=] {
|
| 652 |
-
int arr[N]; // OK: not an odr-use, refers to automatic variable
|
| 653 |
-
f(&N); // OK: causes N to be captured; &N points to the
|
| 654 |
-
// corresponding member of the closure type
|
| 655 |
-
};
|
| 656 |
-
}
|
| 657 |
-
```
|
| 658 |
|
| 659 |
Every occurrence of `decltype((x))` where `x` is a possibly
|
| 660 |
parenthesized *id-expression* that names an entity of automatic storage
|
| 661 |
duration is treated as if `x` were transformed into an access to a
|
| 662 |
corresponding data member of the closure type that would have been
|
| 663 |
declared if `x` were an odr-use of the denoted entity.
|
| 664 |
|
|
|
|
|
|
|
| 665 |
``` cpp
|
| 666 |
void f3() {
|
| 667 |
float x, &r = x;
|
| 668 |
[=] { // x and r are not captured (appearance in a decltype operand is not an odr-use)
|
| 669 |
decltype(x) y1; // y1 has type float
|
| 670 |
-
decltype((x)) y2 = y1; // y2 has type float const& because this lambda
|
| 671 |
-
// is not mutable and x is an lvalue
|
| 672 |
decltype(r) r1 = y1; // r1 has type float& (transformation not considered)
|
| 673 |
decltype((r)) r2 = y2; // r2 has type float const&
|
| 674 |
};
|
| 675 |
}
|
| 676 |
```
|
| 677 |
|
| 678 |
-
|
| 679 |
-
[[dcl.fct.def.delete]]) default constructor and a deleted copy
|
| 680 |
-
assignment operator. It has an implicitly-declared copy constructor (
|
| 681 |
-
[[class.copy]]) and may have an implicitly-declared move constructor (
|
| 682 |
-
[[class.copy]]). The copy/move constructor is implicitly defined in the
|
| 683 |
-
same way as any other implicitly declared copy/move constructor would be
|
| 684 |
-
implicitly defined.
|
| 685 |
-
|
| 686 |
-
The closure type associated with a *lambda-expression* has an
|
| 687 |
-
implicitly-declared destructor ([[class.dtor]]).
|
| 688 |
|
| 689 |
When the *lambda-expression* is evaluated, the entities that are
|
| 690 |
captured by copy are used to direct-initialize each corresponding
|
| 691 |
non-static data member of the resulting closure object, and the
|
| 692 |
non-static data members corresponding to the *init-capture*s are
|
| 693 |
initialized as indicated by the corresponding *initializer* (which may
|
| 694 |
be copy- or direct-initialization). (For array members, the array
|
| 695 |
elements are direct-initialized in increasing subscript order.) These
|
| 696 |
initializations are performed in the (unspecified) order in which the
|
| 697 |
-
non-static data members are declared.
|
| 698 |
-
will occur in the reverse order of the constructions.
|
| 699 |
|
| 700 |
-
|
| 701 |
-
|
| 702 |
-
|
| 703 |
-
|
|
|
|
|
|
|
|
|
|
| 704 |
|
| 705 |
A *simple-capture* followed by an ellipsis is a pack expansion (
|
| 706 |
[[temp.variadic]]). An *init-capture* followed by an ellipsis is
|
| 707 |
ill-formed.
|
| 708 |
|
|
|
|
|
|
|
| 709 |
``` cpp
|
| 710 |
template<class... Args>
|
| 711 |
void f(Args... args) {
|
| 712 |
auto lm = [&, args...] { return g(args...); };
|
| 713 |
lm();
|
| 714 |
}
|
| 715 |
```
|
| 716 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
## Primary expressions <a id="expr.prim">[[expr.prim]]</a>
|
| 2 |
|
|
|
|
|
|
|
| 3 |
``` bnf
|
| 4 |
primary-expression:
|
| 5 |
literal
|
| 6 |
'this'
|
| 7 |
'(' expression ')'
|
| 8 |
id-expression
|
| 9 |
lambda-expression
|
| 10 |
+
fold-expression
|
| 11 |
```
|
| 12 |
|
| 13 |
+
### Literals <a id="expr.prim.literal">[[expr.prim.literal]]</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
A *literal* is a primary expression. Its type depends on its form (
|
| 16 |
[[lex.literal]]). A string literal is an lvalue; all other literals are
|
| 17 |
prvalues.
|
| 18 |
|
| 19 |
+
### This <a id="expr.prim.this">[[expr.prim.this]]</a>
|
| 20 |
+
|
| 21 |
The keyword `this` names a pointer to the object for which a non-static
|
| 22 |
member function ([[class.this]]) is invoked or a non-static data
|
| 23 |
member’s initializer ([[class.mem]]) is evaluated.
|
| 24 |
|
| 25 |
If a declaration declares a member function or member function template
|
| 26 |
of a class `X`, the expression `this` is a prvalue of type “pointer to
|
| 27 |
+
*cv-qualifier-seq* `X`” between the optional *cv-qualifier-seq* and the
|
| 28 |
end of the *function-definition*, *member-declarator*, or *declarator*.
|
| 29 |
It shall not appear before the optional *cv-qualifier-seq* and it shall
|
| 30 |
not appear within the declaration of a static member function (although
|
| 31 |
its type and value category are defined within a static member function
|
| 32 |
+
as they are within a non-static member function).
|
| 33 |
+
|
| 34 |
+
[*Note 1*: This is because declaration matching does not occur until
|
| 35 |
+
the complete declarator is known. — *end note*]
|
| 36 |
+
|
| 37 |
+
Unlike the object expression in other contexts, `*this` is not required
|
| 38 |
+
to be of complete type for purposes of class member access (
|
| 39 |
+
[[expr.ref]]) outside the member function body.
|
| 40 |
+
|
| 41 |
+
[*Note 2*: Only class members declared prior to the declaration are
|
| 42 |
+
visible. — *end note*]
|
| 43 |
+
|
| 44 |
+
[*Example 1*:
|
| 45 |
|
| 46 |
``` cpp
|
| 47 |
struct A {
|
| 48 |
char g();
|
| 49 |
template<class T> auto f(T t) -> decltype(t + g())
|
| 50 |
{ return t + g(); }
|
| 51 |
};
|
| 52 |
template auto A::f(int t) -> decltype(t + g());
|
| 53 |
```
|
| 54 |
|
| 55 |
+
— *end example*]
|
| 56 |
+
|
| 57 |
Otherwise, if a *member-declarator* declares a non-static data member (
|
| 58 |
[[class.mem]]) of a class `X`, the expression `this` is a prvalue of
|
| 59 |
+
type “pointer to `X`” within the optional default member initializer (
|
| 60 |
+
[[class.mem]]). It shall not appear elsewhere in the
|
| 61 |
+
*member-declarator*.
|
| 62 |
|
| 63 |
The expression `this` shall not appear in any other context.
|
| 64 |
|
| 65 |
+
[*Example 2*:
|
| 66 |
+
|
| 67 |
``` cpp
|
| 68 |
class Outer {
|
| 69 |
int a[sizeof(*this)]; // error: not inside a member function
|
| 70 |
+
unsigned int sz = sizeof(*this); // OK: in default member initializer
|
| 71 |
|
| 72 |
void f() {
|
| 73 |
int b[sizeof(*this)]; // OK
|
| 74 |
|
| 75 |
struct Inner {
|
|
|
|
| 77 |
};
|
| 78 |
}
|
| 79 |
};
|
| 80 |
```
|
| 81 |
|
| 82 |
+
— *end example*]
|
| 83 |
+
|
| 84 |
+
### Parentheses <a id="expr.prim.paren">[[expr.prim.paren]]</a>
|
| 85 |
+
|
| 86 |
+
A parenthesized expression `(E)` is a primary expression whose type,
|
| 87 |
+
value, and value category are identical to those of `E`. The
|
| 88 |
parenthesized expression can be used in exactly the same contexts as
|
| 89 |
+
those where `E` can be used, and with the same meaning, except as
|
| 90 |
+
otherwise indicated.
|
| 91 |
|
| 92 |
+
### Names <a id="expr.prim.id">[[expr.prim.id]]</a>
|
| 93 |
+
|
| 94 |
+
``` bnf
|
| 95 |
+
id-expression:
|
| 96 |
+
unqualified-id
|
| 97 |
+
qualified-id
|
| 98 |
+
```
|
| 99 |
+
|
| 100 |
+
An *id-expression* is a restricted form of a *primary-expression*.
|
| 101 |
+
|
| 102 |
+
[*Note 1*: An *id-expression* can appear after `.` and `->` operators (
|
| 103 |
+
[[expr.ref]]). — *end note*]
|
| 104 |
+
|
| 105 |
+
An *id-expression* that denotes a non-static data member or non-static
|
| 106 |
+
member function of a class can only be used:
|
| 107 |
+
|
| 108 |
+
- as part of a class member access ([[expr.ref]]) in which the object
|
| 109 |
+
expression refers to the member’s class[^4] or a class derived from
|
| 110 |
+
that class, or
|
| 111 |
+
- to form a pointer to member ([[expr.unary.op]]), or
|
| 112 |
+
- if that *id-expression* denotes a non-static data member and it
|
| 113 |
+
appears in an unevaluated operand.
|
| 114 |
+
\[*Example 1*:
|
| 115 |
+
``` cpp
|
| 116 |
+
struct S {
|
| 117 |
+
int m;
|
| 118 |
+
};
|
| 119 |
+
int i = sizeof(S::m); // OK
|
| 120 |
+
int j = sizeof(S::m + 42); // OK
|
| 121 |
+
```
|
| 122 |
+
|
| 123 |
+
— *end example*]
|
| 124 |
+
|
| 125 |
+
#### Unqualified names <a id="expr.prim.id.unqual">[[expr.prim.id.unqual]]</a>
|
| 126 |
+
|
| 127 |
+
``` bnf
|
| 128 |
+
unqualified-id:
|
| 129 |
+
identifier
|
| 130 |
+
operator-function-id
|
| 131 |
+
conversion-function-id
|
| 132 |
+
literal-operator-id
|
| 133 |
+
'~' class-name
|
| 134 |
+
'~' decltype-specifier
|
| 135 |
+
template-id
|
| 136 |
+
```
|
| 137 |
|
| 138 |
An *identifier* is an *id-expression* provided it has been suitably
|
| 139 |
+
declared (Clause [[dcl.dcl]]).
|
| 140 |
+
|
| 141 |
+
[*Note 1*: For *operator-function-id*s, see [[over.oper]]; for
|
| 142 |
+
*conversion-function-id*s, see [[class.conv.fct]]; for
|
| 143 |
+
*literal-operator-id*s, see [[over.literal]]; for *template-id*s, see
|
| 144 |
+
[[temp.names]]. A *class-name* or *decltype-specifier* prefixed by `~`
|
| 145 |
+
denotes a destructor; see [[class.dtor]]. Within the definition of a
|
| 146 |
+
non-static member function, an *identifier* that names a non-static
|
| 147 |
member is transformed to a class member access expression (
|
| 148 |
+
[[class.mfct.non-static]]). — *end note*]
|
| 149 |
+
|
| 150 |
+
The type of the expression is the type of the *identifier*. The result
|
| 151 |
+
is the entity denoted by the identifier. The expression is an lvalue if
|
| 152 |
+
the entity is a function, variable, or data member and a prvalue
|
| 153 |
+
otherwise; it is a bit-field if the identifier designates a bit-field (
|
| 154 |
+
[[dcl.struct.bind]]).
|
| 155 |
+
|
| 156 |
+
#### Qualified names <a id="expr.prim.id.qual">[[expr.prim.id.qual]]</a>
|
| 157 |
|
| 158 |
``` bnf
|
| 159 |
qualified-id:
|
| 160 |
nested-name-specifier 'template'ₒₚₜ unqualified-id
|
| 161 |
```
|
|
|
|
| 176 |
A *nested-name-specifier* that denotes a class, optionally followed by
|
| 177 |
the keyword `template` ([[temp.names]]), and then followed by the name
|
| 178 |
of a member of either that class ([[class.mem]]) or one of its base
|
| 179 |
classes (Clause [[class.derived]]), is a *qualified-id*;
|
| 180 |
[[class.qual]] describes name lookup for class members that appear in
|
| 181 |
+
*qualified-id*s. The result is the member. The type of the result is the
|
| 182 |
type of the member. The result is an lvalue if the member is a static
|
| 183 |
+
member function or a data member and a prvalue otherwise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
|
| 185 |
+
[*Note 1*: A class member can be referred to using a *qualified-id* at
|
| 186 |
+
any point in its potential scope (
|
| 187 |
+
[[basic.scope.class]]). — *end note*]
|
| 188 |
+
|
| 189 |
+
Where *class-name* `::~` *class-name* is used, the two *class-name*s
|
| 190 |
+
shall refer to the same class; this notation names the destructor (
|
| 191 |
+
[[class.dtor]]). The form `~` *decltype-specifier* also denotes the
|
| 192 |
+
destructor, but it shall not be used as the *unqualified-id* in a
|
| 193 |
+
*qualified-id*.
|
| 194 |
+
|
| 195 |
+
[*Note 2*: A *typedef-name* that names a class is a *class-name* (
|
| 196 |
+
[[class.name]]). — *end note*]
|
| 197 |
+
|
| 198 |
+
The *nested-name-specifier* `::` names the global namespace. A
|
| 199 |
+
*nested-name-specifier* that names a namespace ([[basic.namespace]]),
|
| 200 |
+
optionally followed by the keyword `template` ([[temp.names]]), and
|
| 201 |
+
then followed by the name of a member of that namespace (or the name of
|
| 202 |
+
a member of a namespace made visible by a *using-directive*), is a
|
| 203 |
+
*qualified-id*; [[namespace.qual]] describes name lookup for namespace
|
| 204 |
+
members that appear in *qualified-id*s. The result is the member. The
|
| 205 |
+
type of the result is the type of the member. The result is an lvalue if
|
| 206 |
+
the member is a function or a variable and a prvalue otherwise.
|
| 207 |
|
| 208 |
A *nested-name-specifier* that denotes an enumeration ([[dcl.enum]]),
|
| 209 |
followed by the name of an enumerator of that enumeration, is a
|
| 210 |
*qualified-id* that refers to the enumerator. The result is the
|
| 211 |
enumerator. The type of the result is the type of the enumeration. The
|
|
|
|
| 214 |
In a *qualified-id*, if the *unqualified-id* is a
|
| 215 |
*conversion-function-id*, its *conversion-type-id* shall denote the same
|
| 216 |
type in both the context in which the entire *qualified-id* occurs and
|
| 217 |
in the context of the class denoted by the *nested-name-specifier*.
|
| 218 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
### Lambda expressions <a id="expr.prim.lambda">[[expr.prim.lambda]]</a>
|
| 220 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 221 |
``` bnf
|
| 222 |
lambda-expression:
|
| 223 |
lambda-introducer lambda-declaratorₒₚₜ compound-statement
|
| 224 |
```
|
| 225 |
|
| 226 |
``` bnf
|
| 227 |
lambda-introducer:
|
| 228 |
'[' lambda-captureₒₚₜ ']'
|
| 229 |
```
|
| 230 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
``` bnf
|
| 232 |
lambda-declarator:
|
| 233 |
+
'(' parameter-declaration-clause ')' decl-specifier-seqₒₚₜ
|
| 234 |
+
noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ trailing-return-typeₒₚₜ
|
| 235 |
```
|
| 236 |
|
| 237 |
+
Lambda expressions provide a concise way to create simple function
|
| 238 |
+
objects.
|
| 239 |
+
|
| 240 |
+
[*Example 1*:
|
| 241 |
+
|
| 242 |
+
``` cpp
|
| 243 |
+
#include <algorithm>
|
| 244 |
+
#include <cmath>
|
| 245 |
+
void abssort(float* x, unsigned N) {
|
| 246 |
+
std::sort(x, x + N, [](float a, float b) { return std::abs(a) < std::abs(b); });
|
| 247 |
+
}
|
| 248 |
+
```
|
| 249 |
+
|
| 250 |
+
— *end example*]
|
| 251 |
+
|
| 252 |
+
A *lambda-expression* is a prvalue whose result object is called the
|
| 253 |
+
*closure object*. A *lambda-expression* shall not appear in an
|
| 254 |
+
unevaluated operand (Clause [[expr]]), in a *template-argument*, in an
|
| 255 |
+
*alias-declaration*, in a typedef declaration, or in the declaration of
|
| 256 |
+
a function or function template outside its function body and default
|
| 257 |
+
arguments.
|
| 258 |
+
|
| 259 |
+
[*Note 1*: The intention is to prevent lambdas from appearing in a
|
| 260 |
+
signature. — *end note*]
|
| 261 |
+
|
| 262 |
+
[*Note 2*: A closure object behaves like a function object (
|
| 263 |
+
[[function.objects]]). — *end note*]
|
| 264 |
+
|
| 265 |
+
In the *decl-specifier-seq* of the *lambda-declarator*, each
|
| 266 |
+
*decl-specifier* shall either be `mutable` or `constexpr`.
|
| 267 |
+
|
| 268 |
+
If a *lambda-expression* does not include a *lambda-declarator*, it is
|
| 269 |
+
as if the *lambda-declarator* were `()`. The lambda return type is
|
| 270 |
+
`auto`, which is replaced by the type specified by the
|
| 271 |
+
*trailing-return-type* if provided and/or deduced from `return`
|
| 272 |
+
statements as described in [[dcl.spec.auto]].
|
| 273 |
+
|
| 274 |
+
[*Example 2*:
|
| 275 |
+
|
| 276 |
+
``` cpp
|
| 277 |
+
auto x1 = [](int i){ return i; }; // OK: return type is int
|
| 278 |
+
auto x2 = []{ return { 1, 2 }; }; // error: deducing return type from braced-init-list
|
| 279 |
+
int j;
|
| 280 |
+
auto x3 = []()->auto&& { return j; }; // OK: return type is int&
|
| 281 |
+
```
|
| 282 |
+
|
| 283 |
+
— *end example*]
|
| 284 |
+
|
| 285 |
+
#### Closure types <a id="expr.prim.lambda.closure">[[expr.prim.lambda.closure]]</a>
|
| 286 |
+
|
| 287 |
+
The type of a *lambda-expression* (which is also the type of the closure
|
| 288 |
+
object) is a unique, unnamed non-union class type, called the *closure
|
| 289 |
+
type*, whose properties are described below.
|
| 290 |
+
|
| 291 |
+
The closure type is declared in the smallest block scope, class scope,
|
| 292 |
+
or namespace scope that contains the corresponding *lambda-expression*.
|
| 293 |
+
|
| 294 |
+
[*Note 1*: This determines the set of namespaces and classes associated
|
| 295 |
+
with the closure type ([[basic.lookup.argdep]]). The parameter types of
|
| 296 |
+
a *lambda-declarator* do not affect these associated namespaces and
|
| 297 |
+
classes. — *end note*]
|
| 298 |
+
|
| 299 |
+
The closure type is not an aggregate type ([[dcl.init.aggr]]). An
|
| 300 |
+
implementation may define the closure type differently from what is
|
| 301 |
+
described below provided this does not alter the observable behavior of
|
| 302 |
+
the program other than by changing:
|
| 303 |
|
| 304 |
- the size and/or alignment of the closure type,
|
| 305 |
- whether the closure type is trivially copyable (Clause [[class]]),
|
| 306 |
- whether the closure type is a standard-layout class (Clause
|
| 307 |
[[class]]), or
|
| 308 |
- whether the closure type is a POD class (Clause [[class]]).
|
| 309 |
|
| 310 |
An implementation shall not add members of rvalue reference type to the
|
| 311 |
closure type.
|
| 312 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 313 |
The closure type for a non-generic *lambda-expression* has a public
|
| 314 |
inline function call operator ([[over.call]]) whose parameters and
|
| 315 |
return type are described by the *lambda-expression*’s
|
| 316 |
*parameter-declaration-clause* and *trailing-return-type* respectively.
|
| 317 |
For a generic lambda, the closure type has a public inline function call
|
|
|
|
| 325 |
*lambda-expression*'s *trailing-return-type* and
|
| 326 |
*parameter-declaration-clause* by replacing each occurrence of `auto` in
|
| 327 |
the *decl-specifier*s of the *parameter-declaration-clause* with the
|
| 328 |
name of the corresponding invented *template-parameter*.
|
| 329 |
|
| 330 |
+
[*Example 1*:
|
| 331 |
+
|
| 332 |
``` cpp
|
| 333 |
auto glambda = [](auto a, auto&& b) { return a < b; };
|
| 334 |
bool b = glambda(3, 3.14); // OK
|
| 335 |
+
|
| 336 |
auto vglambda = [](auto printer) {
|
| 337 |
return [=](auto&& ... ts) { // OK: ts is a function parameter pack
|
| 338 |
printer(std::forward<decltype(ts)>(ts)...);
|
| 339 |
|
| 340 |
return [=]() {
|
|
|
|
| 346 |
{ std::cout << v1 << v2 << v3; } );
|
| 347 |
auto q = p(1, 'a', 3.14); // OK: outputs 1a3.14
|
| 348 |
q(); // OK: outputs 1a3.14
|
| 349 |
```
|
| 350 |
|
| 351 |
+
— *end example*]
|
| 352 |
+
|
| 353 |
+
The function call operator or operator template is declared `const` (
|
| 354 |
[[class.mfct.non-static]]) if and only if the *lambda-expression*’s
|
| 355 |
*parameter-declaration-clause* is not followed by `mutable`. It is
|
| 356 |
+
neither virtual nor declared `volatile`. Any *noexcept-specifier*
|
| 357 |
specified on a *lambda-expression* applies to the corresponding function
|
| 358 |
call operator or operator template. An *attribute-specifier-seq* in a
|
| 359 |
*lambda-declarator* appertains to the type of the corresponding function
|
| 360 |
+
call operator or operator template. The function call operator or any
|
| 361 |
+
given operator template specialization is a constexpr function if either
|
| 362 |
+
the corresponding *lambda-expression*'s *parameter-declaration-clause*
|
| 363 |
+
is followed by `constexpr`, or it satisfies the requirements for a
|
| 364 |
+
constexpr function ([[dcl.constexpr]]).
|
| 365 |
+
|
| 366 |
+
[*Note 2*: Names referenced in the *lambda-declarator* are looked up in
|
| 367 |
+
the context in which the *lambda-expression* appears. — *end note*]
|
| 368 |
+
|
| 369 |
+
[*Example 2*:
|
| 370 |
+
|
| 371 |
+
``` cpp
|
| 372 |
+
auto ID = [](auto a) { return a; };
|
| 373 |
+
static_assert(ID(3) == 3); // OK
|
| 374 |
+
|
| 375 |
+
struct NonLiteral {
|
| 376 |
+
NonLiteral(int n) : n(n) { }
|
| 377 |
+
int n;
|
| 378 |
+
};
|
| 379 |
+
static_assert(ID(NonLiteral{3}).n == 3); // ill-formed
|
| 380 |
+
```
|
| 381 |
+
|
| 382 |
+
— *end example*]
|
| 383 |
+
|
| 384 |
+
[*Example 3*:
|
| 385 |
+
|
| 386 |
+
``` cpp
|
| 387 |
+
auto monoid = [](auto v) { return [=] { return v; }; };
|
| 388 |
+
auto add = [](auto m1) constexpr {
|
| 389 |
+
auto ret = m1();
|
| 390 |
+
return [=](auto m2) mutable {
|
| 391 |
+
auto m1val = m1();
|
| 392 |
+
auto plus = [=](auto m2val) mutable constexpr
|
| 393 |
+
{ return m1val += m2val; };
|
| 394 |
+
ret = plus(m2());
|
| 395 |
+
return monoid(ret);
|
| 396 |
+
};
|
| 397 |
+
};
|
| 398 |
+
constexpr auto zero = monoid(0);
|
| 399 |
+
constexpr auto one = monoid(1);
|
| 400 |
+
static_assert(add(one)(zero)() == one()); // OK
|
| 401 |
+
|
| 402 |
+
// Since two below is not declared constexpr, an evaluation of its constexpr member function call operator
|
| 403 |
+
// cannot perform an lvalue-to-rvalue conversion on one of its subobjects (that represents its capture)
|
| 404 |
+
// in a constant expression.
|
| 405 |
+
auto two = monoid(2);
|
| 406 |
+
assert(two() == 2); // OK, not a constant expression.
|
| 407 |
+
static_assert(add(one)(one)() == two()); // ill-formed: two() is not a constant expression
|
| 408 |
+
static_assert(add(one)(one)() == monoid(2)()); // OK
|
| 409 |
+
```
|
| 410 |
+
|
| 411 |
+
— *end example*]
|
| 412 |
|
| 413 |
The closure type for a non-generic *lambda-expression* with no
|
| 414 |
+
*lambda-capture* has a conversion function to pointer to function with
|
| 415 |
+
C++language linkage ([[dcl.link]]) having the same parameter and return
|
| 416 |
+
types as the closure type’s function call operator. The conversion is to
|
| 417 |
+
“pointer to `noexcept` function” if the function call operator has a
|
| 418 |
+
non-throwing exception specification. The value returned by this
|
| 419 |
+
conversion function is the address of a function `F` that, when invoked,
|
| 420 |
+
has the same effect as invoking the closure type’s function call
|
| 421 |
+
operator. `F` is a constexpr function if the function call operator is a
|
| 422 |
+
constexpr function. For a generic lambda with no *lambda-capture*, the
|
| 423 |
+
closure type has a conversion function template to pointer to function.
|
| 424 |
+
The conversion function template has the same invented
|
| 425 |
*template-parameter-list*, and the pointer to function has the same
|
| 426 |
parameter types, as the function call operator template. The return type
|
| 427 |
of the pointer to function shall behave as if it were a
|
| 428 |
*decltype-specifier* denoting the return type of the corresponding
|
| 429 |
+
function call operator template specialization.
|
| 430 |
+
|
| 431 |
+
[*Note 3*:
|
| 432 |
+
|
| 433 |
+
If the generic lambda has no *trailing-return-type* or the
|
| 434 |
+
*trailing-return-type* contains a placeholder type, return type
|
| 435 |
+
deduction of the corresponding function call operator template
|
| 436 |
+
specialization has to be done. The corresponding specialization is that
|
| 437 |
+
instantiation of the function call operator template with the same
|
| 438 |
+
template arguments as those deduced for the conversion function
|
| 439 |
+
template. Consider the following:
|
| 440 |
|
| 441 |
``` cpp
|
| 442 |
auto glambda = [](auto a) { return a; };
|
| 443 |
int (*fp)(int) = glambda;
|
| 444 |
```
|
|
|
|
| 460 |
template<class T> operator fptr_t<T>() const
|
| 461 |
{ return &lambda_call_operator_invoker; }
|
| 462 |
};
|
| 463 |
```
|
| 464 |
|
| 465 |
+
— *end note*]
|
| 466 |
+
|
| 467 |
+
[*Example 4*:
|
| 468 |
+
|
| 469 |
``` cpp
|
| 470 |
void f1(int (*)(int)) { }
|
| 471 |
void f2(char (*)(int)) { }
|
| 472 |
|
| 473 |
void g(int (*)(int)) { } // #1
|
|
|
|
| 482 |
g(glambda); // error: ambiguous
|
| 483 |
h(glambda); // OK: calls #3 since it is convertible from ID
|
| 484 |
int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
|
| 485 |
```
|
| 486 |
|
| 487 |
+
— *end example*]
|
| 488 |
+
|
| 489 |
The value returned by any given specialization of this conversion
|
| 490 |
+
function template is the address of a function `F` that, when invoked,
|
| 491 |
has the same effect as invoking the generic lambda’s corresponding
|
| 492 |
+
function call operator template specialization. `F` is a constexpr
|
| 493 |
+
function if the corresponding specialization is a constexpr function.
|
| 494 |
+
|
| 495 |
+
[*Note 4*: This will result in the implicit instantiation of the
|
| 496 |
+
generic lambda’s body. The instantiated generic lambda’s return type and
|
| 497 |
+
parameter types shall match the return type and parameter types of the
|
| 498 |
+
pointer to function. — *end note*]
|
| 499 |
+
|
| 500 |
+
[*Example 5*:
|
| 501 |
|
| 502 |
``` cpp
|
| 503 |
auto GL = [](auto a) { std::cout << a; return a; };
|
| 504 |
int (*GL_int)(int) = GL; // OK: through conversion function template
|
| 505 |
GL_int(3); // OK: same as GL(3)
|
| 506 |
```
|
| 507 |
|
| 508 |
+
— *end example*]
|
| 509 |
+
|
| 510 |
+
The conversion function or conversion function template is public,
|
| 511 |
+
constexpr, non-virtual, non-explicit, const, and has a non-throwing
|
| 512 |
+
exception specification ([[except.spec]]).
|
| 513 |
+
|
| 514 |
+
[*Example 6*:
|
| 515 |
+
|
| 516 |
+
``` cpp
|
| 517 |
+
auto Fwd = [](int (*fp)(int), auto a) { return fp(a); };
|
| 518 |
+
auto C = [](auto a) { return a; };
|
| 519 |
+
|
| 520 |
+
static_assert(Fwd(C,3) == 3); // OK
|
| 521 |
+
|
| 522 |
+
// No specialization of the function call operator template can be constexpr (due to the local static).
|
| 523 |
+
auto NC = [](auto a) { static int s; return a; };
|
| 524 |
+
static_assert(Fwd(NC,3) == 3); // ill-formed
|
| 525 |
+
```
|
| 526 |
+
|
| 527 |
+
— *end example*]
|
| 528 |
+
|
| 529 |
The *lambda-expression*’s *compound-statement* yields the
|
| 530 |
*function-body* ([[dcl.fct.def]]) of the function call operator, but
|
| 531 |
for purposes of name lookup ([[basic.lookup]]), determining the type
|
| 532 |
and value of `this` ([[class.this]]) and transforming *id-expression*s
|
| 533 |
referring to non-static class members into class member access
|
| 534 |
expressions using `(*this)` ([[class.mfct.non-static]]), the
|
| 535 |
*compound-statement* is considered in the context of the
|
| 536 |
*lambda-expression*.
|
| 537 |
|
| 538 |
+
[*Example 7*:
|
| 539 |
+
|
| 540 |
``` cpp
|
| 541 |
struct S1 {
|
| 542 |
int x, y;
|
| 543 |
int operator()(int);
|
| 544 |
void f() {
|
|
|
|
| 548 |
};
|
| 549 |
}
|
| 550 |
};
|
| 551 |
```
|
| 552 |
|
| 553 |
+
— *end example*]
|
| 554 |
+
|
| 555 |
Further, a variable `__func__` is implicitly defined at the beginning of
|
| 556 |
the *compound-statement* of the *lambda-expression*, with semantics as
|
| 557 |
described in [[dcl.fct.def.general]].
|
| 558 |
|
| 559 |
+
The closure type associated with a *lambda-expression* has no default
|
| 560 |
+
constructor and a deleted copy assignment operator. It has a defaulted
|
| 561 |
+
copy constructor and a defaulted move constructor ([[class.copy]]).
|
| 562 |
+
|
| 563 |
+
[*Note 5*: These special member functions are implicitly defined as
|
| 564 |
+
usual, and might therefore be defined as deleted. — *end note*]
|
| 565 |
+
|
| 566 |
+
The closure type associated with a *lambda-expression* has an
|
| 567 |
+
implicitly-declared destructor ([[class.dtor]]).
|
| 568 |
+
|
| 569 |
+
A member of a closure type shall not be explicitly instantiated (
|
| 570 |
+
[[temp.explicit]]), explicitly specialized ([[temp.expl.spec]]), or
|
| 571 |
+
named in a `friend` declaration ([[class.friend]]).
|
| 572 |
+
|
| 573 |
+
#### Captures <a id="expr.prim.lambda.capture">[[expr.prim.lambda.capture]]</a>
|
| 574 |
+
|
| 575 |
+
``` bnf
|
| 576 |
+
lambda-capture:
|
| 577 |
+
capture-default
|
| 578 |
+
capture-list
|
| 579 |
+
capture-default ',' capture-list
|
| 580 |
+
```
|
| 581 |
+
|
| 582 |
+
``` bnf
|
| 583 |
+
capture-default:
|
| 584 |
+
'&'
|
| 585 |
+
'='
|
| 586 |
+
```
|
| 587 |
+
|
| 588 |
+
``` bnf
|
| 589 |
+
capture-list:
|
| 590 |
+
capture '...'ₒₚₜ
|
| 591 |
+
capture-list ',' capture '...'ₒₚₜ
|
| 592 |
+
```
|
| 593 |
+
|
| 594 |
+
``` bnf
|
| 595 |
+
capture:
|
| 596 |
+
simple-capture
|
| 597 |
+
init-capture
|
| 598 |
+
```
|
| 599 |
+
|
| 600 |
+
``` bnf
|
| 601 |
+
simple-capture:
|
| 602 |
+
identifier
|
| 603 |
+
'&' identifier
|
| 604 |
+
'this'
|
| 605 |
+
'* this'
|
| 606 |
+
```
|
| 607 |
+
|
| 608 |
+
``` bnf
|
| 609 |
+
init-capture:
|
| 610 |
+
identifier initializer
|
| 611 |
+
'&' identifier initializer
|
| 612 |
+
```
|
| 613 |
+
|
| 614 |
+
The body of a *lambda-expression* may refer to variables with automatic
|
| 615 |
+
storage duration and the `*this` object (if any) of enclosing block
|
| 616 |
+
scopes by capturing those entities, as described below.
|
| 617 |
+
|
| 618 |
If a *lambda-capture* includes a *capture-default* that is `&`, no
|
| 619 |
identifier in a *simple-capture* of that *lambda-capture* shall be
|
| 620 |
preceded by `&`. If a *lambda-capture* includes a *capture-default* that
|
| 621 |
is `=`, each *simple-capture* of that *lambda-capture* shall be of the
|
| 622 |
+
form “`&` *identifier*” or “`* this`”.
|
| 623 |
+
|
| 624 |
+
[*Note 1*: The form `[&,this]` is redundant but accepted for
|
| 625 |
+
compatibility with ISO C++14. — *end note*]
|
| 626 |
+
|
| 627 |
+
Ignoring appearances in *initializer*s of *init-capture*s, an identifier
|
| 628 |
+
or `this` shall not appear more than once in a *lambda-capture*.
|
| 629 |
+
|
| 630 |
+
[*Example 1*:
|
| 631 |
|
| 632 |
``` cpp
|
| 633 |
struct S2 { void f(int i); };
|
| 634 |
void S2::f(int i) {
|
| 635 |
[&, i]{ }; // OK
|
| 636 |
[&, &i]{ }; // error: i preceded by & when & is the default
|
| 637 |
+
[=, *this]{ }; // OK
|
| 638 |
[=, this]{ }; // error: this when = is the default
|
| 639 |
[i, i]{ }; // error: i repeated
|
| 640 |
+
[this, *this]{ }; // error: this appears twice
|
| 641 |
}
|
| 642 |
```
|
| 643 |
|
| 644 |
+
— *end example*]
|
| 645 |
+
|
| 646 |
A *lambda-expression* whose smallest enclosing scope is a block scope (
|
| 647 |
[[basic.scope.block]]) is a *local lambda expression*; any other
|
| 648 |
*lambda-expression* shall not have a *capture-default* or
|
| 649 |
*simple-capture* in its *lambda-introducer*. The *reaching scope* of a
|
| 650 |
local lambda expression is the set of enclosing scopes up to and
|
| 651 |
+
including the innermost enclosing function and its parameters.
|
| 652 |
+
|
| 653 |
+
[*Note 2*: This reaching scope includes any intervening
|
| 654 |
+
*lambda-expression*s. — *end note*]
|
| 655 |
|
| 656 |
The *identifier* in a *simple-capture* is looked up using the usual
|
| 657 |
rules for unqualified name lookup ([[basic.lookup.unqual]]); each such
|
| 658 |
lookup shall find an entity. An entity that is designated by a
|
| 659 |
*simple-capture* is said to be *explicitly captured*, and shall be
|
| 660 |
+
`*this` (when the *simple-capture* is “`this`” or “`* this`”) or a
|
| 661 |
+
variable with automatic storage duration declared in the reaching scope
|
| 662 |
+
of the local lambda expression.
|
| 663 |
+
|
| 664 |
+
If an *identifier* in a *simple-capture* appears as the *declarator-id*
|
| 665 |
+
of a parameter of the *lambda-declarator*'s
|
| 666 |
+
*parameter-declaration-clause*, the program is ill-formed.
|
| 667 |
+
|
| 668 |
+
[*Example 2*:
|
| 669 |
+
|
| 670 |
+
``` cpp
|
| 671 |
+
void f() {
|
| 672 |
+
int x = 0;
|
| 673 |
+
auto g = [x](int x) { return 0; } // error: parameter and simple-capture have the same name
|
| 674 |
+
}
|
| 675 |
+
```
|
| 676 |
+
|
| 677 |
+
— *end example*]
|
| 678 |
|
| 679 |
An *init-capture* behaves as if it declares and explicitly captures a
|
| 680 |
variable of the form “`auto` *init-capture* `;`” whose declarative
|
| 681 |
region is the *lambda-expression*’s *compound-statement*, except that:
|
| 682 |
|
|
|
|
| 686 |
non-static data member, and no additional copy and destruction is
|
| 687 |
performed, and
|
| 688 |
- if the capture is by reference, the variable’s lifetime ends when the
|
| 689 |
closure object’s lifetime ends.
|
| 690 |
|
| 691 |
+
[*Note 3*: This enables an *init-capture* like “`x = std::move(x)`”;
|
| 692 |
+
the second “`x`” must bind to a declaration in the surrounding
|
| 693 |
+
context. — *end note*]
|
| 694 |
+
|
| 695 |
+
[*Example 3*:
|
| 696 |
|
| 697 |
``` cpp
|
| 698 |
int x = 4;
|
| 699 |
auto y = [&r = x, x = x+1]()->int {
|
| 700 |
r += 2;
|
| 701 |
return x+2;
|
| 702 |
}(); // Updates ::x to 6, and initializes y to 7.
|
| 703 |
+
|
| 704 |
+
auto z = [a = 42](int a) { return 1; } // error: parameter and local variable have the same name
|
| 705 |
```
|
| 706 |
|
| 707 |
+
— *end example*]
|
| 708 |
+
|
| 709 |
A *lambda-expression* with an associated *capture-default* that does not
|
| 710 |
+
explicitly capture `*this` or a variable with automatic storage duration
|
| 711 |
(this excludes any *id-expression* that has been found to refer to an
|
| 712 |
*init-capture*'s associated non-static data member), is said to
|
| 713 |
+
*implicitly capture* the entity (i.e., `*this` or a variable) if the
|
| 714 |
*compound-statement*:
|
| 715 |
|
| 716 |
+
- odr-uses ([[basic.def.odr]]) the entity (in the case of a variable),
|
| 717 |
+
- odr-uses ([[basic.def.odr]]) `this` (in the case of the object
|
| 718 |
+
designated by `*this`), or
|
| 719 |
- names the entity in a potentially-evaluated expression (
|
| 720 |
[[basic.def.odr]]) where the enclosing full-expression depends on a
|
| 721 |
generic lambda parameter declared within the reaching scope of the
|
| 722 |
*lambda-expression*.
|
| 723 |
|
| 724 |
+
[*Example 4*:
|
| 725 |
+
|
| 726 |
``` cpp
|
| 727 |
void f(int, const int (&)[2] = {}) { } // #1
|
| 728 |
void f(const int&, const int (&)[1]) { } // #2
|
| 729 |
void test() {
|
| 730 |
const int x = 17;
|
|
|
|
| 737 |
f(x, selector); // OK: is a dependent expression, so captures x
|
| 738 |
};
|
| 739 |
}
|
| 740 |
```
|
| 741 |
|
| 742 |
+
— *end example*]
|
| 743 |
+
|
| 744 |
All such implicitly captured entities shall be declared within the
|
| 745 |
+
reaching scope of the lambda expression.
|
| 746 |
+
|
| 747 |
+
[*Note 4*: The implicit capture of an entity by a nested
|
| 748 |
+
*lambda-expression* can cause its implicit capture by the containing
|
| 749 |
+
*lambda-expression* (see below). Implicit odr-uses of `this` can result
|
| 750 |
+
in implicit capture. — *end note*]
|
| 751 |
|
| 752 |
An entity is *captured* if it is captured explicitly or implicitly. An
|
| 753 |
entity captured by a *lambda-expression* is odr-used (
|
| 754 |
[[basic.def.odr]]) in the scope containing the *lambda-expression*. If
|
| 755 |
+
`*this` is captured by a local lambda expression, its nearest enclosing
|
| 756 |
function shall be a non-static member function. If a *lambda-expression*
|
| 757 |
or an instantiation of the function call operator template of a generic
|
| 758 |
lambda odr-uses ([[basic.def.odr]]) `this` or a variable with automatic
|
| 759 |
storage duration from its reaching scope, that entity shall be captured
|
| 760 |
by the *lambda-expression*. If a *lambda-expression* captures an entity
|
| 761 |
and that entity is not defined or captured in the immediately enclosing
|
| 762 |
lambda expression or function, the program is ill-formed.
|
| 763 |
|
| 764 |
+
[*Example 5*:
|
| 765 |
+
|
| 766 |
``` cpp
|
| 767 |
void f1(int i) {
|
| 768 |
int const N = 20;
|
| 769 |
auto m1 = [=]{
|
| 770 |
int const M = 30;
|
| 771 |
auto m2 = [i]{
|
| 772 |
int x[N][M]; // OK: N and M are not odr-used
|
| 773 |
+
x[0][0] = i; // OK: i is explicitly captured by m2 and implicitly captured by m1
|
|
|
|
| 774 |
};
|
| 775 |
};
|
| 776 |
struct s1 {
|
| 777 |
int f;
|
| 778 |
void work(int n) {
|
| 779 |
int m = n*n;
|
| 780 |
int j = 40;
|
| 781 |
auto m3 = [this,m] {
|
| 782 |
auto m4 = [&,j] { // error: j not captured by m3
|
| 783 |
+
int x = n; // error: n implicitly captured by m4 but not captured by m3
|
| 784 |
+
x += m; // OK: m implicitly captured by m4 and explicitly captured by m3
|
|
|
|
|
|
|
| 785 |
x += i; // error: i is outside of the reaching scope
|
| 786 |
+
x += f; // OK: this captured implicitly by m4 and explicitly by m3
|
|
|
|
| 787 |
};
|
| 788 |
};
|
| 789 |
}
|
| 790 |
};
|
| 791 |
}
|
| 792 |
+
|
| 793 |
+
struct s2 {
|
| 794 |
+
double ohseven = .007;
|
| 795 |
+
auto f() {
|
| 796 |
+
return [this] {
|
| 797 |
+
return [*this] {
|
| 798 |
+
return ohseven; // OK
|
| 799 |
+
}
|
| 800 |
+
}();
|
| 801 |
+
}
|
| 802 |
+
auto g() {
|
| 803 |
+
return [] {
|
| 804 |
+
return [*this] { }; // error: *this not captured by outer lambda-expression
|
| 805 |
+
}();
|
| 806 |
+
}
|
| 807 |
+
};
|
| 808 |
```
|
| 809 |
|
| 810 |
+
— *end example*]
|
| 811 |
+
|
| 812 |
A *lambda-expression* appearing in a default argument shall not
|
| 813 |
implicitly or explicitly capture any entity.
|
| 814 |
|
| 815 |
+
[*Example 6*:
|
| 816 |
+
|
| 817 |
``` cpp
|
| 818 |
void f2() {
|
| 819 |
int i = 1;
|
| 820 |
void g1(int = ([i]{ return i; })()); // ill-formed
|
| 821 |
void g2(int = ([i]{ return 0; })()); // ill-formed
|
|
|
|
| 823 |
void g4(int = ([=]{ return 0; })()); // OK
|
| 824 |
void g5(int = ([]{ return sizeof i; })()); // OK
|
| 825 |
}
|
| 826 |
```
|
| 827 |
|
| 828 |
+
— *end example*]
|
| 829 |
+
|
| 830 |
+
An entity is *captured by copy* if
|
| 831 |
+
|
| 832 |
+
- it is implicitly captured, the *capture-default* is `=`, and the
|
| 833 |
+
captured entity is not `*this`, or
|
| 834 |
+
- it is explicitly captured with a capture that is not of the form
|
| 835 |
+
`this`, `&` *identifier*, or `&` *identifier* *initializer*.
|
| 836 |
+
|
| 837 |
+
For each entity captured by copy, an unnamed non-static data member is
|
| 838 |
+
declared in the closure type. The declaration order of these members is
|
| 839 |
+
unspecified. The type of such a data member is the referenced type if
|
| 840 |
+
the entity is a reference to an object, an lvalue reference to the
|
| 841 |
+
referenced function type if the entity is a reference to a function, or
|
| 842 |
+
the type of the corresponding captured entity otherwise. A member of an
|
| 843 |
+
anonymous union shall not be captured by copy.
|
| 844 |
+
|
| 845 |
+
Every *id-expression* within the *compound-statement* of a
|
| 846 |
+
*lambda-expression* that is an odr-use ([[basic.def.odr]]) of an entity
|
| 847 |
+
captured by copy is transformed into an access to the corresponding
|
| 848 |
+
unnamed data member of the closure type.
|
| 849 |
+
|
| 850 |
+
[*Note 5*: An *id-expression* that is not an odr-use refers to the
|
| 851 |
+
original entity, never to a member of the closure type. Furthermore,
|
| 852 |
+
such an *id-expression* does not cause the implicit capture of the
|
| 853 |
+
entity. — *end note*]
|
| 854 |
+
|
| 855 |
+
If `*this` is captured by copy, each odr-use of `this` is transformed
|
| 856 |
+
into a pointer to the corresponding unnamed data member of the closure
|
| 857 |
+
type, cast ([[expr.cast]]) to the type of `this`.
|
| 858 |
+
|
| 859 |
+
[*Note 6*: The cast ensures that the transformed expression is a
|
| 860 |
+
prvalue. — *end note*]
|
| 861 |
+
|
| 862 |
+
An *id-expression* within the *compound-statement* of a
|
| 863 |
+
*lambda-expression* that is an odr-use of a reference captured by
|
| 864 |
+
reference refers to the entity to which the captured reference is bound
|
| 865 |
+
and not to the captured reference.
|
| 866 |
+
|
| 867 |
+
[*Note 7*: The validity of such captures is determined by the lifetime
|
| 868 |
+
of the object to which the reference refers, not by the lifetime of the
|
| 869 |
+
reference itself. — *end note*]
|
| 870 |
+
|
| 871 |
+
[*Example 7*:
|
| 872 |
+
|
| 873 |
+
``` cpp
|
| 874 |
+
void f(const int*);
|
| 875 |
+
void g() {
|
| 876 |
+
const int N = 10;
|
| 877 |
+
[=] {
|
| 878 |
+
int arr[N]; // OK: not an odr-use, refers to automatic variable
|
| 879 |
+
f(&N); // OK: causes N to be captured; &N points to
|
| 880 |
+
// the corresponding member of the closure type
|
| 881 |
+
};
|
| 882 |
+
}
|
| 883 |
+
auto h(int &r) {
|
| 884 |
+
return [&] {
|
| 885 |
+
++r; // Valid after h returns if the lifetime of the
|
| 886 |
+
// object to which r is bound has not ended
|
| 887 |
+
};
|
| 888 |
+
}
|
| 889 |
+
```
|
| 890 |
+
|
| 891 |
+
— *end example*]
|
| 892 |
|
| 893 |
An entity is *captured by reference* if it is implicitly or explicitly
|
| 894 |
captured but not captured by copy. It is unspecified whether additional
|
| 895 |
unnamed non-static data members are declared in the closure type for
|
| 896 |
+
entities captured by reference. If declared, such non-static data
|
| 897 |
+
members shall be of literal type.
|
| 898 |
+
|
| 899 |
+
[*Example 8*:
|
| 900 |
+
|
| 901 |
+
``` cpp
|
| 902 |
+
// The inner closure type must be a literal type regardless of how reference captures are represented.
|
| 903 |
+
static_assert([](int n) { return [&n] { return ++n; }(); }(3) == 4);
|
| 904 |
+
```
|
| 905 |
+
|
| 906 |
+
— *end example*]
|
| 907 |
+
|
| 908 |
+
A bit-field or a member of an anonymous union shall not be captured by
|
| 909 |
+
reference.
|
| 910 |
|
| 911 |
If a *lambda-expression* `m2` captures an entity and that entity is
|
| 912 |
captured by an immediately enclosing *lambda-expression* `m1`, then
|
| 913 |
`m2`’s capture is transformed as follows:
|
| 914 |
|
| 915 |
- if `m1` captures the entity by copy, `m2` captures the corresponding
|
| 916 |
non-static data member of `m1`’s closure type;
|
| 917 |
- if `m1` captures the entity by reference, `m2` captures the same
|
| 918 |
entity captured by `m1`.
|
| 919 |
|
| 920 |
+
[*Example 9*:
|
| 921 |
+
|
| 922 |
+
The nested lambda expressions and invocations below will output
|
| 923 |
`123234`.
|
| 924 |
|
| 925 |
``` cpp
|
| 926 |
int a = 1, b = 1, c = 1;
|
| 927 |
auto m1 = [a, &b, &c]() mutable {
|
|
|
|
| 935 |
a = 2; b = 2; c = 2;
|
| 936 |
m1();
|
| 937 |
std::cout << a << b << c;
|
| 938 |
```
|
| 939 |
|
| 940 |
+
— *end example*]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 941 |
|
| 942 |
Every occurrence of `decltype((x))` where `x` is a possibly
|
| 943 |
parenthesized *id-expression* that names an entity of automatic storage
|
| 944 |
duration is treated as if `x` were transformed into an access to a
|
| 945 |
corresponding data member of the closure type that would have been
|
| 946 |
declared if `x` were an odr-use of the denoted entity.
|
| 947 |
|
| 948 |
+
[*Example 10*:
|
| 949 |
+
|
| 950 |
``` cpp
|
| 951 |
void f3() {
|
| 952 |
float x, &r = x;
|
| 953 |
[=] { // x and r are not captured (appearance in a decltype operand is not an odr-use)
|
| 954 |
decltype(x) y1; // y1 has type float
|
| 955 |
+
decltype((x)) y2 = y1; // y2 has type float const& because this lambda is not mutable and x is an lvalue
|
|
|
|
| 956 |
decltype(r) r1 = y1; // r1 has type float& (transformation not considered)
|
| 957 |
decltype((r)) r2 = y2; // r2 has type float const&
|
| 958 |
};
|
| 959 |
}
|
| 960 |
```
|
| 961 |
|
| 962 |
+
— *end example*]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 963 |
|
| 964 |
When the *lambda-expression* is evaluated, the entities that are
|
| 965 |
captured by copy are used to direct-initialize each corresponding
|
| 966 |
non-static data member of the resulting closure object, and the
|
| 967 |
non-static data members corresponding to the *init-capture*s are
|
| 968 |
initialized as indicated by the corresponding *initializer* (which may
|
| 969 |
be copy- or direct-initialization). (For array members, the array
|
| 970 |
elements are direct-initialized in increasing subscript order.) These
|
| 971 |
initializations are performed in the (unspecified) order in which the
|
| 972 |
+
non-static data members are declared.
|
|
|
|
| 973 |
|
| 974 |
+
[*Note 8*: This ensures that the destructions will occur in the reverse
|
| 975 |
+
order of the constructions. — *end note*]
|
| 976 |
+
|
| 977 |
+
[*Note 9*: If a non-reference entity is implicitly or explicitly
|
| 978 |
+
captured by reference, invoking the function call operator of the
|
| 979 |
+
corresponding *lambda-expression* after the lifetime of the entity has
|
| 980 |
+
ended is likely to result in undefined behavior. — *end note*]
|
| 981 |
|
| 982 |
A *simple-capture* followed by an ellipsis is a pack expansion (
|
| 983 |
[[temp.variadic]]). An *init-capture* followed by an ellipsis is
|
| 984 |
ill-formed.
|
| 985 |
|
| 986 |
+
[*Example 11*:
|
| 987 |
+
|
| 988 |
``` cpp
|
| 989 |
template<class... Args>
|
| 990 |
void f(Args... args) {
|
| 991 |
auto lm = [&, args...] { return g(args...); };
|
| 992 |
lm();
|
| 993 |
}
|
| 994 |
```
|
| 995 |
|
| 996 |
+
— *end example*]
|
| 997 |
+
|
| 998 |
+
### Fold expressions <a id="expr.prim.fold">[[expr.prim.fold]]</a>
|
| 999 |
+
|
| 1000 |
+
A fold expression performs a fold of a template parameter pack (
|
| 1001 |
+
[[temp.variadic]]) over a binary operator.
|
| 1002 |
+
|
| 1003 |
+
``` bnf
|
| 1004 |
+
fold-expression:
|
| 1005 |
+
'(' cast-expression fold-operator '...' ')'
|
| 1006 |
+
'(' '...' fold-operator cast-expression ')'
|
| 1007 |
+
'(' cast-expression fold-operator '...' fold-operator cast-expression ')'
|
| 1008 |
+
```
|
| 1009 |
+
|
| 1010 |
+
``` bnf
|
| 1011 |
+
%% Ed. note: character protrusion would misalign operators with leading `-`.
|
| 1012 |
+
|
| 1013 |
+
fold-operator: one of
|
| 1014 |
+
'+ ' '- ' '* ' '/ ' '% ' '^ ' '& ' '| ' '<< ' '>> '
|
| 1015 |
+
'+=' '-=' '*=' '/=' '%=' '^=' '&=' '|=' '<<=' '>>=' '='
|
| 1016 |
+
'==' '!=' '< ' '> ' '<=' '>=' '&&' '||' ', ' '.* ' '->*'
|
| 1017 |
+
```
|
| 1018 |
+
|
| 1019 |
+
An expression of the form `(...` *op* `e)` where *op* is a
|
| 1020 |
+
*fold-operator* is called a *unary left fold*. An expression of the form
|
| 1021 |
+
`(e` *op* `...)` where *op* is a *fold-operator* is called a *unary
|
| 1022 |
+
right fold*. Unary left folds and unary right folds are collectively
|
| 1023 |
+
called *unary folds*. In a unary fold, the *cast-expression* shall
|
| 1024 |
+
contain an unexpanded parameter pack ([[temp.variadic]]).
|
| 1025 |
+
|
| 1026 |
+
An expression of the form `(e1` *op1* `...` *op2* `e2)` where *op1* and
|
| 1027 |
+
*op2* are *fold-operator*s is called a *binary fold*. In a binary fold,
|
| 1028 |
+
*op1* and *op2* shall be the same *fold-operator*, and either `e1` shall
|
| 1029 |
+
contain an unexpanded parameter pack or `e2` shall contain an unexpanded
|
| 1030 |
+
parameter pack, but not both. If `e2` contains an unexpanded parameter
|
| 1031 |
+
pack, the expression is called a *binary left fold*. If `e1` contains an
|
| 1032 |
+
unexpanded parameter pack, the expression is called a *binary right
|
| 1033 |
+
fold*.
|
| 1034 |
+
|
| 1035 |
+
[*Example 1*:
|
| 1036 |
+
|
| 1037 |
+
``` cpp
|
| 1038 |
+
template<typename ...Args>
|
| 1039 |
+
bool f(Args ...args) {
|
| 1040 |
+
return (true && ... && args); // OK
|
| 1041 |
+
}
|
| 1042 |
+
|
| 1043 |
+
template<typename ...Args>
|
| 1044 |
+
bool f(Args ...args) {
|
| 1045 |
+
return (args + ... + args); // error: both operands contain unexpanded parameter packs
|
| 1046 |
+
}
|
| 1047 |
+
```
|
| 1048 |
+
|
| 1049 |
+
— *end example*]
|
| 1050 |
+
|