- tmp/tmpu8wqb_qu/{from.md → to.md} +385 -240
tmp/tmpu8wqb_qu/{from.md → to.md}
RENAMED
|
@@ -11,35 +11,43 @@ primary-expression:
|
|
| 11 |
requires-expression
|
| 12 |
```
|
| 13 |
|
| 14 |
### Literals <a id="expr.prim.literal">[[expr.prim.literal]]</a>
|
| 15 |
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
value category as the corresponding
|
| 20 |
-
in [[lex.ext]], and any other
|
|
|
|
| 21 |
|
| 22 |
### This <a id="expr.prim.this">[[expr.prim.this]]</a>
|
| 23 |
|
| 24 |
-
The keyword `this` names a pointer to the object for which
|
| 25 |
-
member function [[class.
|
| 26 |
-
initializer [[class.mem]] is evaluated.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
|
| 28 |
If a declaration declares a member function or member function template
|
| 29 |
of a class `X`, the expression `this` is a prvalue of type “pointer to
|
| 30 |
-
*cv-qualifier-seq* `X`”
|
| 31 |
-
end of the *function-definition*,
|
| 32 |
-
It shall not appear
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
|
|
|
| 36 |
|
| 37 |
-
[*Note
|
| 38 |
the complete declarator is known. — *end note*]
|
| 39 |
|
| 40 |
-
[*Note
|
| 41 |
|
| 42 |
In a *trailing-return-type*, the class being defined is not required to
|
| 43 |
be complete for purposes of class member access [[expr.ref]]. Class
|
| 44 |
members declared later are not visible.
|
| 45 |
|
|
@@ -58,21 +66,21 @@ template auto A::f(int t) -> decltype(t + g());
|
|
| 58 |
|
| 59 |
— *end note*]
|
| 60 |
|
| 61 |
Otherwise, if a *member-declarator* declares a non-static data member
|
| 62 |
[[class.mem]] of a class `X`, the expression `this` is a prvalue of type
|
| 63 |
-
“pointer to `X`”
|
| 64 |
-
[[class.mem]].
|
| 65 |
|
| 66 |
The expression `this` shall not appear in any other context.
|
| 67 |
|
| 68 |
[*Example 2*:
|
| 69 |
|
| 70 |
``` cpp
|
| 71 |
class Outer {
|
| 72 |
int a[sizeof(*this)]; // error: not inside a member function
|
| 73 |
-
unsigned int sz = sizeof(*this); // OK
|
| 74 |
|
| 75 |
void f() {
|
| 76 |
int b[sizeof(*this)]; // OK
|
| 77 |
|
| 78 |
struct Inner {
|
|
@@ -85,16 +93,19 @@ class Outer {
|
|
| 85 |
— *end example*]
|
| 86 |
|
| 87 |
### Parentheses <a id="expr.prim.paren">[[expr.prim.paren]]</a>
|
| 88 |
|
| 89 |
A parenthesized expression `(E)` is a primary expression whose type,
|
| 90 |
-
|
| 91 |
-
expression can be used in exactly the same contexts as
|
| 92 |
-
be used, and with the same meaning, except as
|
|
|
|
| 93 |
|
| 94 |
### Names <a id="expr.prim.id">[[expr.prim.id]]</a>
|
| 95 |
|
|
|
|
|
|
|
| 96 |
``` bnf
|
| 97 |
id-expression:
|
| 98 |
unqualified-id
|
| 99 |
qualified-id
|
| 100 |
```
|
|
@@ -102,63 +113,71 @@ id-expression:
|
|
| 102 |
An *id-expression* is a restricted form of a *primary-expression*.
|
| 103 |
|
| 104 |
[*Note 1*: An *id-expression* can appear after `.` and `->` operators
|
| 105 |
[[expr.ref]]. — *end note*]
|
| 106 |
|
| 107 |
-
|
| 108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
|
| 110 |
- as part of a class member access [[expr.ref]] in which the object
|
| 111 |
expression refers to the member’s class[^10] or a class derived from
|
| 112 |
that class, or
|
| 113 |
- to form a pointer to member [[expr.unary.op]], or
|
| 114 |
- if that *id-expression* denotes a non-static data member and it
|
| 115 |
appears in an unevaluated operand.
|
| 116 |
-
\[*Example
|
| 117 |
``` cpp
|
| 118 |
struct S {
|
| 119 |
int m;
|
| 120 |
};
|
| 121 |
int i = sizeof(S::m); // OK
|
| 122 |
int j = sizeof(S::m + 42); // OK
|
| 123 |
```
|
| 124 |
|
| 125 |
— *end example*]
|
| 126 |
|
| 127 |
-
A potentially-evaluated *id-expression* that denotes an immediate
|
| 128 |
-
function [[dcl.constexpr]] shall appear only
|
| 129 |
-
|
| 130 |
-
- as a subexpression of an immediate invocation, or
|
| 131 |
-
- in an immediate function context [[expr.const]].
|
| 132 |
-
|
| 133 |
For an *id-expression* that denotes an overload set, overload resolution
|
| 134 |
-
is performed to select a unique function
|
| 135 |
-
[[over.over]]).
|
| 136 |
|
| 137 |
-
[*Note
|
| 138 |
|
| 139 |
A program cannot refer to a function with a trailing *requires-clause*
|
| 140 |
whose *constraint-expression* is not satisfied, because such functions
|
| 141 |
are never selected by overload resolution.
|
| 142 |
|
| 143 |
-
[*Example
|
| 144 |
|
| 145 |
``` cpp
|
| 146 |
template<typename T> struct A {
|
| 147 |
static void f(int) requires false;
|
| 148 |
-
}
|
| 149 |
|
| 150 |
void g() {
|
| 151 |
A<int>::f(0); // error: cannot call f
|
| 152 |
void (*p1)(int) = A<int>::f; // error: cannot take the address of f
|
| 153 |
decltype(A<int>::f)* p2 = nullptr; // error: the type decltype(A<int>::f) is invalid
|
| 154 |
}
|
| 155 |
```
|
| 156 |
|
| 157 |
In each case, the constraints of `f` are not satisfied. In the
|
| 158 |
declaration of `p2`, those constraints are required to be satisfied even
|
| 159 |
-
though `f` is an unevaluated operand [[
|
| 160 |
|
| 161 |
— *end example*]
|
| 162 |
|
| 163 |
— *end note*]
|
| 164 |
|
|
@@ -185,56 +204,109 @@ the copy of the parameter [[dcl.fct.def.coroutine]].
|
|
| 185 |
*literal-operator-id*s, see [[over.literal]]; for *template-id*s, see
|
| 186 |
[[temp.names]]. A *type-name* or *decltype-specifier* prefixed by `~`
|
| 187 |
denotes the destructor of the type so named; see [[expr.prim.id.dtor]].
|
| 188 |
Within the definition of a non-static member function, an *identifier*
|
| 189 |
that names a non-static member is transformed to a class member access
|
| 190 |
-
expression
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
type of such an identifier will typically be `const`
|
| 203 |
qualified. — *end note*]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
[*Note 3*: If the entity is a template parameter object for a template
|
| 208 |
parameter of type `T` [[temp.param]], the type of the expression is
|
| 209 |
`const T`. — *end note*]
|
| 210 |
|
| 211 |
-
[*Note
|
| 212 |
it is cv-qualified or is a reference type. — *end note*]
|
| 213 |
|
| 214 |
-
The expression is an
|
| 215 |
-
|
| 216 |
-
|
| 217 |
-
|
|
|
|
| 218 |
|
| 219 |
[*Example 1*:
|
| 220 |
|
| 221 |
``` cpp
|
| 222 |
void f() {
|
| 223 |
float x, &r = x;
|
| 224 |
-
|
|
|
|
|
|
|
| 225 |
decltype(x) y1; // y1 has type float
|
| 226 |
-
decltype((x)) y2 = y1; // y2 has type float const&
|
| 227 |
-
// is not mutable and x is an lvalue
|
| 228 |
decltype(r) r1 = y1; // r1 has type float&
|
| 229 |
decltype((r)) r2 = y2; // r2 has type float const&
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 230 |
};
|
| 231 |
}
|
| 232 |
```
|
| 233 |
|
| 234 |
— *end example*]
|
| 235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 236 |
#### Qualified names <a id="expr.prim.id.qual">[[expr.prim.id.qual]]</a>
|
| 237 |
|
| 238 |
``` bnf
|
| 239 |
qualified-id:
|
| 240 |
nested-name-specifier templateₒₚₜ unqualified-id
|
|
@@ -248,56 +320,66 @@ nested-name-specifier:
|
|
| 248 |
decltype-specifier '::'
|
| 249 |
nested-name-specifier identifier '::'
|
| 250 |
nested-name-specifier templateₒₚₜ simple-template-id '::'
|
| 251 |
```
|
| 252 |
|
| 253 |
-
The
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
| 262 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 263 |
and a prvalue otherwise.
|
| 264 |
|
| 265 |
-
[*Note 1*: A class member can be referred to using a *qualified-id* at
|
| 266 |
-
any point in its potential scope [[basic.scope.class]]. — *end note*]
|
| 267 |
-
|
| 268 |
-
Where *type-name* `::~` *type-name* is used, the two *type-name*s shall
|
| 269 |
-
refer to the same type (ignoring cv-qualifications); this notation
|
| 270 |
-
denotes the destructor of the type so named [[expr.prim.id.dtor]]. The
|
| 271 |
-
*unqualified-id* in a *qualified-id* shall not be of the form
|
| 272 |
-
`~`*decltype-specifier*.
|
| 273 |
-
|
| 274 |
-
The *nested-name-specifier* `::` names the global namespace. A
|
| 275 |
-
*nested-name-specifier* that names a namespace [[basic.namespace]],
|
| 276 |
-
optionally followed by the keyword `template` [[temp.names]], and then
|
| 277 |
-
followed by the name of a member of that namespace (or the name of a
|
| 278 |
-
member of a namespace made visible by a *using-directive*), is a
|
| 279 |
-
*qualified-id*; [[namespace.qual]] describes name lookup for namespace
|
| 280 |
-
members that appear in *qualified-id*s. The result is the member. The
|
| 281 |
-
type of the result is the type of the member. The result is an lvalue if
|
| 282 |
-
the member is a function, a variable, or a structured binding
|
| 283 |
-
[[dcl.struct.bind]] and a prvalue otherwise.
|
| 284 |
-
|
| 285 |
-
A *nested-name-specifier* that denotes an enumeration [[dcl.enum]],
|
| 286 |
-
followed by the name of an enumerator of that enumeration, is a
|
| 287 |
-
*qualified-id* that refers to the enumerator. The result is the
|
| 288 |
-
enumerator. The type of the result is the type of the enumeration. The
|
| 289 |
-
result is a prvalue.
|
| 290 |
-
|
| 291 |
-
In a *qualified-id*, if the *unqualified-id* is a
|
| 292 |
-
*conversion-function-id*, its *conversion-type-id* is first looked up in
|
| 293 |
-
the class denoted by the *nested-name-specifier* of the *qualified-id*
|
| 294 |
-
and the name, if found, is used. Otherwise, it is looked up in the
|
| 295 |
-
context in which the entire *qualified-id* occurs. In each of these
|
| 296 |
-
lookups, only names that denote types or templates whose specializations
|
| 297 |
-
are types are considered.
|
| 298 |
-
|
| 299 |
#### Destruction <a id="expr.prim.id.dtor">[[expr.prim.id.dtor]]</a>
|
| 300 |
|
| 301 |
An *id-expression* that denotes the destructor of a type `T` names the
|
| 302 |
destructor of `T` if `T` is a class type [[class.dtor]], otherwise the
|
| 303 |
*id-expression* is said to name a *pseudo-destructor*.
|
|
@@ -305,12 +387,12 @@ destructor of `T` if `T` is a class type [[class.dtor]], otherwise the
|
|
| 305 |
If the *id-expression* names a pseudo-destructor, `T` shall be a scalar
|
| 306 |
type and the *id-expression* shall appear as the right operand of a
|
| 307 |
class member access [[expr.ref]] that forms the *postfix-expression* of
|
| 308 |
a function call [[expr.call]].
|
| 309 |
|
| 310 |
-
[*Note 1*: Such a call ends the lifetime of the object
|
| 311 |
-
[[basic.life]]
|
| 312 |
|
| 313 |
[*Example 1*:
|
| 314 |
|
| 315 |
``` cpp
|
| 316 |
struct C { };
|
|
@@ -327,25 +409,45 @@ void f() {
|
|
| 327 |
|
| 328 |
— *end example*]
|
| 329 |
|
| 330 |
### Lambda expressions <a id="expr.prim.lambda">[[expr.prim.lambda]]</a>
|
| 331 |
|
|
|
|
|
|
|
| 332 |
``` bnf
|
| 333 |
lambda-expression:
|
| 334 |
-
lambda-introducer
|
| 335 |
-
lambda-introducer '<' template-parameter-list '>' requires-clauseₒₚₜ
|
|
|
|
| 336 |
```
|
| 337 |
|
| 338 |
``` bnf
|
| 339 |
lambda-introducer:
|
| 340 |
'[' lambda-captureₒₚₜ ']'
|
| 341 |
```
|
| 342 |
|
| 343 |
``` bnf
|
| 344 |
lambda-declarator:
|
| 345 |
-
|
| 346 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 347 |
```
|
| 348 |
|
| 349 |
A *lambda-expression* provides a concise way to create a simple function
|
| 350 |
object.
|
| 351 |
|
|
@@ -365,29 +467,46 @@ A *lambda-expression* is a prvalue whose result object is called the
|
|
| 365 |
*closure object*.
|
| 366 |
|
| 367 |
[*Note 1*: A closure object behaves like a function object
|
| 368 |
[[function.objects]]. — *end note*]
|
| 369 |
|
| 370 |
-
|
| 371 |
-
*
|
|
|
|
|
|
|
|
|
|
| 372 |
|
| 373 |
-
[*Note 2*:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 374 |
[[dcl.decl]]. — *end note*]
|
| 375 |
|
| 376 |
-
If a *lambda-
|
| 377 |
-
|
| 378 |
-
|
| 379 |
-
*trailing-return-type*
|
| 380 |
-
|
|
|
|
|
|
|
| 381 |
|
| 382 |
[*Example 2*:
|
| 383 |
|
| 384 |
``` cpp
|
| 385 |
-
auto x1 = [](int i){ return i; };
|
| 386 |
auto x2 = []{ return { 1, 2 }; }; // error: deducing return type from braced-init-list
|
| 387 |
int j;
|
| 388 |
-
auto x3 = []()->auto&& { return j; };
|
| 389 |
```
|
| 390 |
|
| 391 |
— *end example*]
|
| 392 |
|
| 393 |
A lambda is a *generic lambda* if the *lambda-expression* has any
|
|
@@ -395,12 +514,12 @@ generic parameter type placeholders [[dcl.spec.auto]], or if the lambda
|
|
| 395 |
has a *template-parameter-list*.
|
| 396 |
|
| 397 |
[*Example 3*:
|
| 398 |
|
| 399 |
``` cpp
|
| 400 |
-
int i = [](int i, auto a) { return i; }(3, 4); // OK
|
| 401 |
-
int j = []<class T>(T t, int i) { return i; }(3, 4); // OK
|
| 402 |
```
|
| 403 |
|
| 404 |
— *end example*]
|
| 405 |
|
| 406 |
#### Closure types <a id="expr.prim.lambda.closure">[[expr.prim.lambda.closure]]</a>
|
|
@@ -439,56 +558,90 @@ and whose *template-parameter-list* consists of the specified
|
|
| 439 |
call operator template is the *requires-clause* immediately following
|
| 440 |
`<` *template-parameter-list* `>`, if any. The trailing
|
| 441 |
*requires-clause* of the function call operator or operator template is
|
| 442 |
the *requires-clause* of the *lambda-declarator*, if any.
|
| 443 |
|
| 444 |
-
[*Note 2*: The function call operator template for a generic lambda
|
| 445 |
-
|
| 446 |
|
| 447 |
[*Example 1*:
|
| 448 |
|
| 449 |
``` cpp
|
| 450 |
auto glambda = [](auto a, auto&& b) { return a < b; };
|
| 451 |
bool b = glambda(3, 3.14); // OK
|
| 452 |
|
| 453 |
auto vglambda = [](auto printer) {
|
| 454 |
-
return [=](auto&& ... ts) { // OK
|
| 455 |
printer(std::forward<decltype(ts)>(ts)...);
|
| 456 |
|
| 457 |
return [=]() {
|
| 458 |
printer(ts ...);
|
| 459 |
};
|
| 460 |
};
|
| 461 |
};
|
| 462 |
auto p = vglambda( [](auto v1, auto v2, auto v3)
|
| 463 |
{ std::cout << v1 << v2 << v3; } );
|
| 464 |
-
auto q = p(1, 'a', 3.14); // OK
|
| 465 |
-
q(); // OK
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 466 |
```
|
| 467 |
|
| 468 |
— *end example*]
|
| 469 |
|
| 470 |
-
The function call operator or operator template is
|
| 471 |
-
[[class.
|
| 472 |
-
*parameter-declaration-clause* is
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 473 |
neither virtual nor declared `volatile`. Any *noexcept-specifier*
|
| 474 |
specified on a *lambda-expression* applies to the corresponding function
|
| 475 |
call operator or operator template. An *attribute-specifier-seq* in a
|
| 476 |
*lambda-declarator* appertains to the type of the corresponding function
|
| 477 |
-
call operator or operator template.
|
| 478 |
-
|
| 479 |
-
|
| 480 |
-
|
| 481 |
-
|
|
|
|
|
|
|
| 482 |
immediate function [[dcl.constexpr]] if the corresponding
|
| 483 |
*lambda-expression*'s *parameter-declaration-clause* is followed by
|
| 484 |
`consteval`.
|
| 485 |
|
| 486 |
-
[*
|
| 487 |
-
the context in which the *lambda-expression* appears. — *end note*]
|
| 488 |
-
|
| 489 |
-
[*Example 2*:
|
| 490 |
|
| 491 |
``` cpp
|
| 492 |
auto ID = [](auto a) { return a; };
|
| 493 |
static_assert(ID(3) == 3); // OK
|
| 494 |
|
|
@@ -499,11 +652,11 @@ struct NonLiteral {
|
|
| 499 |
static_assert(ID(NonLiteral{3}).n == 3); // error
|
| 500 |
```
|
| 501 |
|
| 502 |
— *end example*]
|
| 503 |
|
| 504 |
-
[*Example
|
| 505 |
|
| 506 |
``` cpp
|
| 507 |
auto monoid = [](auto v) { return [=] { return v; }; };
|
| 508 |
auto add = [](auto m1) constexpr {
|
| 509 |
auto ret = m1();
|
|
@@ -528,18 +681,18 @@ static_assert(add(one)(one)() == two()); // error: two() is not a constan
|
|
| 528 |
static_assert(add(one)(one)() == monoid(2)()); // OK
|
| 529 |
```
|
| 530 |
|
| 531 |
— *end example*]
|
| 532 |
|
| 533 |
-
[*Note
|
| 534 |
|
| 535 |
-
The function call operator or operator template
|
| 536 |
[[temp.constr.decl]] by a *type-constraint* [[temp.param]], a
|
| 537 |
*requires-clause* [[temp.pre]], or a trailing *requires-clause*
|
| 538 |
[[dcl.decl]].
|
| 539 |
|
| 540 |
-
[*Example
|
| 541 |
|
| 542 |
``` cpp
|
| 543 |
template <typename T> concept C1 = ...;
|
| 544 |
template <std::size_t N> concept C2 = ...;
|
| 545 |
template <typename A, typename B> concept C3 = ...;
|
|
@@ -560,27 +713,29 @@ The closure type for a non-generic *lambda-expression* with no
|
|
| 560 |
*lambda-capture* whose constraints (if any) are satisfied has a
|
| 561 |
conversion function to pointer to function with C++ language linkage
|
| 562 |
[[dcl.link]] having the same parameter and return types as the closure
|
| 563 |
type’s function call operator. The conversion is to “pointer to
|
| 564 |
`noexcept` function” if the function call operator has a non-throwing
|
| 565 |
-
exception specification.
|
| 566 |
-
|
| 567 |
-
|
| 568 |
-
|
| 569 |
-
|
| 570 |
-
|
| 571 |
-
function
|
|
|
|
|
|
|
| 572 |
|
| 573 |
For a generic lambda with no *lambda-capture*, the closure type has a
|
| 574 |
conversion function template to pointer to function. The conversion
|
| 575 |
function template has the same invented template parameter list, and the
|
| 576 |
pointer to function has the same parameter types, as the function call
|
| 577 |
operator template. The return type of the pointer to function shall
|
| 578 |
behave as if it were a *decltype-specifier* denoting the return type of
|
| 579 |
the corresponding function call operator template specialization.
|
| 580 |
|
| 581 |
-
[*Note
|
| 582 |
|
| 583 |
If the generic lambda has no *trailing-return-type* or the
|
| 584 |
*trailing-return-type* contains a placeholder type, return type
|
| 585 |
deduction of the corresponding function call operator template
|
| 586 |
specialization has to be done. The corresponding specialization is that
|
|
@@ -612,11 +767,11 @@ struct Closure {
|
|
| 612 |
};
|
| 613 |
```
|
| 614 |
|
| 615 |
— *end note*]
|
| 616 |
|
| 617 |
-
[*Example
|
| 618 |
|
| 619 |
``` cpp
|
| 620 |
void f1(int (*)(int)) { }
|
| 621 |
void f2(char (*)(int)) { }
|
| 622 |
|
|
@@ -628,45 +783,49 @@ void h(char (*)(int)) { } // #4
|
|
| 628 |
|
| 629 |
auto glambda = [](auto a) { return a; };
|
| 630 |
f1(glambda); // OK
|
| 631 |
f2(glambda); // error: ID is not convertible
|
| 632 |
g(glambda); // error: ambiguous
|
| 633 |
-
h(glambda); // OK
|
| 634 |
int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
|
| 635 |
```
|
| 636 |
|
| 637 |
— *end example*]
|
| 638 |
|
| 639 |
-
|
| 640 |
-
|
| 641 |
-
|
| 642 |
-
function call operator template specialization
|
| 643 |
-
|
| 644 |
-
|
| 645 |
-
|
| 646 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 647 |
|
| 648 |
-
[*Note
|
| 649 |
generic lambda’s body. The instantiated generic lambda’s return type and
|
| 650 |
parameter types are required to match the return type and parameter
|
| 651 |
types of the pointer to function. — *end note*]
|
| 652 |
|
| 653 |
-
[*Example
|
| 654 |
|
| 655 |
``` cpp
|
| 656 |
auto GL = [](auto a) { std::cout << a; return a; };
|
| 657 |
-
int (*GL_int)(int) = GL; // OK
|
| 658 |
-
GL_int(3); // OK
|
| 659 |
```
|
| 660 |
|
| 661 |
— *end example*]
|
| 662 |
|
| 663 |
The conversion function or conversion function template is public,
|
| 664 |
constexpr, non-virtual, non-explicit, const, and has a non-throwing
|
| 665 |
exception specification [[except.spec]].
|
| 666 |
|
| 667 |
-
[*Example
|
| 668 |
|
| 669 |
``` cpp
|
| 670 |
auto Fwd = [](int (*fp)(int), auto a) { return fp(a); };
|
| 671 |
auto C = [](auto a) { return a; };
|
| 672 |
|
|
@@ -678,18 +837,14 @@ static_assert(Fwd(NC,3) == 3); // error
|
|
| 678 |
```
|
| 679 |
|
| 680 |
— *end example*]
|
| 681 |
|
| 682 |
The *lambda-expression*’s *compound-statement* yields the
|
| 683 |
-
*function-body* [[dcl.fct.def]] of the function call operator, but
|
| 684 |
-
|
| 685 |
-
of `this` [[class.this]] and transforming *id-expression*s referring to
|
| 686 |
-
non-static class members into class member access expressions using
|
| 687 |
-
`(*this)` ([[class.mfct.non-static]]), the *compound-statement* is
|
| 688 |
-
considered in the context of the *lambda-expression*.
|
| 689 |
|
| 690 |
-
[*Example
|
| 691 |
|
| 692 |
``` cpp
|
| 693 |
struct S1 {
|
| 694 |
int x, y;
|
| 695 |
int operator()(int);
|
|
@@ -714,12 +869,12 @@ defaulted default constructor otherwise. It has a defaulted copy
|
|
| 714 |
constructor and a defaulted move constructor [[class.copy.ctor]]. It has
|
| 715 |
a deleted copy assignment operator if the *lambda-expression* has a
|
| 716 |
*lambda-capture* and defaulted copy and move assignment operators
|
| 717 |
otherwise [[class.copy.assign]].
|
| 718 |
|
| 719 |
-
[*Note
|
| 720 |
-
usual,
|
| 721 |
|
| 722 |
The closure type associated with a *lambda-expression* has an
|
| 723 |
implicitly-declared destructor [[class.dtor]].
|
| 724 |
|
| 725 |
A member of a closure type shall not be explicitly instantiated
|
|
@@ -765,13 +920,12 @@ simple-capture:
|
|
| 765 |
init-capture:
|
| 766 |
'...'ₒₚₜ identifier initializer
|
| 767 |
'&' '...'ₒₚₜ identifier initializer
|
| 768 |
```
|
| 769 |
|
| 770 |
-
The body of a *lambda-expression* may refer to
|
| 771 |
-
|
| 772 |
-
scopes by capturing those entities, as described below.
|
| 773 |
|
| 774 |
If a *lambda-capture* includes a *capture-default* that is `&`, no
|
| 775 |
identifier in a *simple-capture* of that *lambda-capture* shall be
|
| 776 |
preceded by `&`. If a *lambda-capture* includes a *capture-default* that
|
| 777 |
is `=`, each *simple-capture* of that *lambda-capture* shall be of the
|
|
@@ -804,35 +958,37 @@ A *lambda-expression* shall not have a *capture-default* or
|
|
| 804 |
*simple-capture* in its *lambda-introducer* unless its innermost
|
| 805 |
enclosing scope is a block scope [[basic.scope.block]] or it appears
|
| 806 |
within a default member initializer and its innermost enclosing scope is
|
| 807 |
the corresponding class scope [[basic.scope.class]].
|
| 808 |
|
| 809 |
-
The *identifier* in a *simple-capture*
|
| 810 |
-
|
| 811 |
-
lookup shall find a local entity. The *simple-capture*s `this` and
|
| 812 |
`* this` denote the local entity `*this`. An entity that is designated
|
| 813 |
by a *simple-capture* is said to be *explicitly captured*.
|
| 814 |
|
| 815 |
-
If an *identifier* in a *
|
| 816 |
-
|
| 817 |
-
|
|
|
|
| 818 |
|
| 819 |
[*Example 2*:
|
| 820 |
|
| 821 |
``` cpp
|
| 822 |
void f() {
|
| 823 |
int x = 0;
|
| 824 |
-
auto g = [x](int x) { return 0; }; // error: parameter and
|
|
|
|
|
|
|
| 825 |
}
|
| 826 |
```
|
| 827 |
|
| 828 |
— *end example*]
|
| 829 |
|
| 830 |
-
An *init-capture*
|
| 831 |
-
|
| 832 |
-
|
| 833 |
-
*
|
| 834 |
|
| 835 |
- if the capture is by copy (see below), the non-static data member
|
| 836 |
declared for the capture and the variable are treated as two different
|
| 837 |
ways of referring to the same object, which has the lifetime of the
|
| 838 |
non-static data member, and no additional copy and destruction is
|
|
@@ -851,11 +1007,14 @@ int x = 4;
|
|
| 851 |
auto y = [&r = x, x = x+1]()->int {
|
| 852 |
r += 2;
|
| 853 |
return x+2;
|
| 854 |
}(); // Updates ::x to 6, and initializes y to 7.
|
| 855 |
|
| 856 |
-
auto z = [a = 42](int a) { return 1; }; // error: parameter and local variable have the same name
|
|
|
|
|
|
|
|
|
|
| 857 |
```
|
| 858 |
|
| 859 |
— *end example*]
|
| 860 |
|
| 861 |
For the purposes of lambda capture, an expression potentially references
|
|
@@ -869,13 +1028,13 @@ local entities as follows:
|
|
| 869 |
*id-expression*. — *end note*]
|
| 870 |
- A `this` expression potentially references `*this`.
|
| 871 |
- A *lambda-expression* potentially references the local entities named
|
| 872 |
by its *simple-capture*s.
|
| 873 |
|
| 874 |
-
If an expression potentially references a local entity within a
|
| 875 |
-
|
| 876 |
-
|
| 877 |
expressions [[expr.typeid]] were ignored, the entity is said to be
|
| 878 |
*implicitly captured* by each intervening *lambda-expression* with an
|
| 879 |
associated *capture-default* that does not explicitly capture it. The
|
| 880 |
implicit capture of `*this` is deprecated when the *capture-default* is
|
| 881 |
`=`; see [[depr.capture.this]].
|
|
@@ -886,38 +1045,38 @@ implicit capture of `*this` is deprecated when the *capture-default* is
|
|
| 886 |
void f(int, const int (&)[2] = {}); // #1
|
| 887 |
void f(const int&, const int (&)[1]); // #2
|
| 888 |
void test() {
|
| 889 |
const int x = 17;
|
| 890 |
auto g = [](auto a) {
|
| 891 |
-
f(x); // OK
|
| 892 |
};
|
| 893 |
|
| 894 |
auto g1 = [=](auto a) {
|
| 895 |
-
f(x); // OK
|
| 896 |
};
|
| 897 |
|
| 898 |
auto g2 = [=](auto a) {
|
| 899 |
int selector[sizeof(a) == 1 ? 1 : 2]{};
|
| 900 |
-
f(x, selector); // OK
|
| 901 |
};
|
| 902 |
|
| 903 |
auto g3 = [=](auto a) {
|
| 904 |
typeid(a + x); // captures x regardless of whether a + x is an unevaluated operand
|
| 905 |
};
|
| 906 |
}
|
| 907 |
```
|
| 908 |
|
| 909 |
-
Within `g1`, an implementation
|
| 910 |
it is not odr-used.
|
| 911 |
|
| 912 |
— *end example*]
|
| 913 |
|
| 914 |
[*Note 4*:
|
| 915 |
|
| 916 |
The set of captured entities is determined syntactically, and entities
|
| 917 |
-
|
| 918 |
-
|
| 919 |
|
| 920 |
[*Example 5*:
|
| 921 |
|
| 922 |
``` cpp
|
| 923 |
template<bool B>
|
|
@@ -933,12 +1092,12 @@ void f(int n) {
|
|
| 933 |
— *end example*]
|
| 934 |
|
| 935 |
— *end note*]
|
| 936 |
|
| 937 |
An entity is *captured* if it is captured explicitly or implicitly. An
|
| 938 |
-
entity captured by a *lambda-expression* is odr-used [[
|
| 939 |
-
|
| 940 |
|
| 941 |
[*Note 5*: As a consequence, if a *lambda-expression* explicitly
|
| 942 |
captures an entity that is not odr-usable, the program is ill-formed
|
| 943 |
[[basic.def.odr]]. — *end note*]
|
| 944 |
|
|
@@ -948,26 +1107,26 @@ captures an entity that is not odr-usable, the program is ill-formed
|
|
| 948 |
void f1(int i) {
|
| 949 |
int const N = 20;
|
| 950 |
auto m1 = [=]{
|
| 951 |
int const M = 30;
|
| 952 |
auto m2 = [i]{
|
| 953 |
-
int x[N][M]; // OK
|
| 954 |
-
x[0][0] = i; // OK
|
| 955 |
};
|
| 956 |
};
|
| 957 |
struct s1 {
|
| 958 |
int f;
|
| 959 |
void work(int n) {
|
| 960 |
int m = n*n;
|
| 961 |
int j = 40;
|
| 962 |
auto m3 = [this,m] {
|
| 963 |
auto m4 = [&,j] { // error: j not odr-usable due to intervening lambda m3
|
| 964 |
int x = n; // error: n is odr-used but not odr-usable due to intervening lambda m3
|
| 965 |
-
x += m; // OK
|
| 966 |
x += i; // error: i is odr-used but not odr-usable
|
| 967 |
// due to intervening function and class scopes
|
| 968 |
-
x += f; // OK
|
| 969 |
};
|
| 970 |
};
|
| 971 |
}
|
| 972 |
};
|
| 973 |
}
|
|
@@ -1030,11 +1189,11 @@ the entity is a reference to an object, an lvalue reference to the
|
|
| 1030 |
referenced function type if the entity is a reference to a function, or
|
| 1031 |
the type of the corresponding captured entity otherwise. A member of an
|
| 1032 |
anonymous union shall not be captured by copy.
|
| 1033 |
|
| 1034 |
Every *id-expression* within the *compound-statement* of a
|
| 1035 |
-
*lambda-expression* that is an odr-use [[
|
| 1036 |
captured by copy is transformed into an access to the corresponding
|
| 1037 |
unnamed data member of the closure type.
|
| 1038 |
|
| 1039 |
[*Note 7*: An *id-expression* that is not an odr-use refers to the
|
| 1040 |
original entity, never to a member of the closure type. However, such an
|
|
@@ -1050,12 +1209,12 @@ the closure type.
|
|
| 1050 |
``` cpp
|
| 1051 |
void f(const int*);
|
| 1052 |
void g() {
|
| 1053 |
const int N = 10;
|
| 1054 |
[=] {
|
| 1055 |
-
int arr[N]; // OK
|
| 1056 |
-
f(&N); // OK
|
| 1057 |
// the corresponding member of the closure type
|
| 1058 |
};
|
| 1059 |
}
|
| 1060 |
```
|
| 1061 |
|
|
@@ -1103,13 +1262,15 @@ auto h(int &r) {
|
|
| 1103 |
|
| 1104 |
If a *lambda-expression* `m2` captures an entity and that entity is
|
| 1105 |
captured by an immediately enclosing *lambda-expression* `m1`, then
|
| 1106 |
`m2`’s capture is transformed as follows:
|
| 1107 |
|
| 1108 |
-
-
|
| 1109 |
-
non-static data member of `m1`’s closure type;
|
| 1110 |
-
|
|
|
|
|
|
|
| 1111 |
entity captured by `m1`.
|
| 1112 |
|
| 1113 |
[*Example 11*:
|
| 1114 |
|
| 1115 |
The nested *lambda-expression*s and invocations below will output
|
|
@@ -1150,12 +1311,11 @@ captured by reference, invoking the function call operator of the
|
|
| 1150 |
corresponding *lambda-expression* after the lifetime of the entity has
|
| 1151 |
ended is likely to result in undefined behavior. — *end note*]
|
| 1152 |
|
| 1153 |
A *simple-capture* containing an ellipsis is a pack expansion
|
| 1154 |
[[temp.variadic]]. An *init-capture* containing an ellipsis is a pack
|
| 1155 |
-
expansion that
|
| 1156 |
-
declarative region is the *lambda-expression*’s *compound-statement*.
|
| 1157 |
|
| 1158 |
[*Example 12*:
|
| 1159 |
|
| 1160 |
``` cpp
|
| 1161 |
template<class... Args>
|
|
@@ -1222,10 +1382,12 @@ bool f(Args ...args) {
|
|
| 1222 |
|
| 1223 |
— *end example*]
|
| 1224 |
|
| 1225 |
### Requires expressions <a id="expr.prim.req">[[expr.prim.req]]</a>
|
| 1226 |
|
|
|
|
|
|
|
| 1227 |
A *requires-expression* provides a concise way to express requirements
|
| 1228 |
on template arguments that can be checked by name lookup
|
| 1229 |
[[basic.lookup]] or by checking properties of types and expressions.
|
| 1230 |
|
| 1231 |
``` bnf
|
|
@@ -1233,22 +1395,22 @@ requires-expression:
|
|
| 1233 |
requires requirement-parameter-listₒₚₜ requirement-body
|
| 1234 |
```
|
| 1235 |
|
| 1236 |
``` bnf
|
| 1237 |
requirement-parameter-list:
|
| 1238 |
-
'(' parameter-declaration-clause
|
| 1239 |
```
|
| 1240 |
|
| 1241 |
``` bnf
|
| 1242 |
requirement-body:
|
| 1243 |
'{' requirement-seq '}'
|
| 1244 |
```
|
| 1245 |
|
| 1246 |
``` bnf
|
| 1247 |
requirement-seq:
|
| 1248 |
requirement
|
| 1249 |
-
requirement
|
| 1250 |
```
|
| 1251 |
|
| 1252 |
``` bnf
|
| 1253 |
requirement:
|
| 1254 |
simple-requirement
|
|
@@ -1257,11 +1419,11 @@ requirement:
|
|
| 1257 |
nested-requirement
|
| 1258 |
```
|
| 1259 |
|
| 1260 |
A *requires-expression* is a prvalue of type `bool` whose value is
|
| 1261 |
described below. Expressions appearing within a *requirement-body* are
|
| 1262 |
-
unevaluated operands [[
|
| 1263 |
|
| 1264 |
[*Example 1*:
|
| 1265 |
|
| 1266 |
A common use of *requires-expression*s is to define requirements in
|
| 1267 |
concepts such as the one below:
|
|
@@ -1289,13 +1451,11 @@ introduces the *requires-expression*.
|
|
| 1289 |
|
| 1290 |
— *end example*]
|
| 1291 |
|
| 1292 |
A *requires-expression* may introduce local parameters using a
|
| 1293 |
*parameter-declaration-clause* [[dcl.fct]]. A local parameter of a
|
| 1294 |
-
*requires-expression* shall not have a default argument.
|
| 1295 |
-
introduced by a local parameter is in scope from the point of its
|
| 1296 |
-
declaration until the closing brace of the *requirement-body*. These
|
| 1297 |
parameters have no linkage, storage, or lifetime; they are only used as
|
| 1298 |
notation for the purpose of defining *requirement*s. The
|
| 1299 |
*parameter-declaration-clause* of a *requirement-parameter-list* shall
|
| 1300 |
not terminate with an ellipsis.
|
| 1301 |
|
|
@@ -1308,14 +1468,10 @@ concept C = requires(T t, ...) { // error: terminates with an ellipsis
|
|
| 1308 |
};
|
| 1309 |
```
|
| 1310 |
|
| 1311 |
— *end example*]
|
| 1312 |
|
| 1313 |
-
The *requirement-body* contains a sequence of *requirement*s. These
|
| 1314 |
-
*requirement*s may refer to local parameters, template parameters, and
|
| 1315 |
-
any other declarations visible from the enclosing context.
|
| 1316 |
-
|
| 1317 |
The substitution of template arguments into a *requires-expression* may
|
| 1318 |
result in the formation of invalid types or expressions in its
|
| 1319 |
*requirement*s or the violation of the semantic constraints of those
|
| 1320 |
*requirement*s. In such cases, the *requires-expression* evaluates to
|
| 1321 |
`false`; it does not cause the program to be ill-formed. The
|
|
@@ -1354,11 +1510,12 @@ simple-requirement:
|
|
| 1354 |
|
| 1355 |
A *simple-requirement* asserts the validity of an *expression*.
|
| 1356 |
|
| 1357 |
[*Note 1*: The enclosing *requires-expression* will evaluate to `false`
|
| 1358 |
if substitution of template arguments into the *expression* fails. The
|
| 1359 |
-
*expression* is an unevaluated operand
|
|
|
|
| 1360 |
|
| 1361 |
[*Example 1*:
|
| 1362 |
|
| 1363 |
``` cpp
|
| 1364 |
template<typename T> concept C =
|
|
@@ -1393,19 +1550,20 @@ if substitution of template arguments fails. — *end note*]
|
|
| 1393 |
template<typename T, typename T::type = 0> struct S;
|
| 1394 |
template<typename T> using Ref = T&;
|
| 1395 |
|
| 1396 |
template<typename T> concept C = requires {
|
| 1397 |
typename T::inner; // required nested member name
|
| 1398 |
-
typename S<T>; // required
|
|
|
|
| 1399 |
typename Ref<T>; // required alias template substitution, fails if T is void
|
| 1400 |
};
|
| 1401 |
```
|
| 1402 |
|
| 1403 |
— *end example*]
|
| 1404 |
|
| 1405 |
A *type-requirement* that names a class template specialization does not
|
| 1406 |
-
require that type to be complete [[
|
| 1407 |
|
| 1408 |
#### Compound requirements <a id="expr.prim.req.compound">[[expr.prim.req.compound]]</a>
|
| 1409 |
|
| 1410 |
``` bnf
|
| 1411 |
compound-requirement:
|
|
@@ -1428,10 +1586,11 @@ properties proceed in the following order:
|
|
| 1428 |
- If the *return-type-requirement* is present, then:
|
| 1429 |
- Substitution of template arguments (if any) into the
|
| 1430 |
*return-type-requirement* is performed.
|
| 1431 |
- The immediately-declared constraint [[temp.param]] of the
|
| 1432 |
*type-constraint* for `decltype((E))` shall be satisfied.
|
|
|
|
| 1433 |
\[*Example 1*:
|
| 1434 |
Given concepts `C` and `D`,
|
| 1435 |
``` cpp
|
| 1436 |
requires {
|
| 1437 |
{ E1 } -> C;
|
|
@@ -1510,19 +1669,5 @@ template<typename T> concept D = requires (T t) {
|
|
| 1510 |
`D<T>` is satisfied if `sizeof(decltype (+t)) == 1`
|
| 1511 |
[[temp.constr.atomic]].
|
| 1512 |
|
| 1513 |
— *end example*]
|
| 1514 |
|
| 1515 |
-
A local parameter shall only appear as an unevaluated operand
|
| 1516 |
-
[[expr.prop]] within the *constraint-expression*.
|
| 1517 |
-
|
| 1518 |
-
[*Example 2*:
|
| 1519 |
-
|
| 1520 |
-
``` cpp
|
| 1521 |
-
template<typename T> concept C = requires (T a) {
|
| 1522 |
-
requires sizeof(a) == 4; // OK
|
| 1523 |
-
requires a == 0; // error: evaluation of a constraint variable
|
| 1524 |
-
};
|
| 1525 |
-
```
|
| 1526 |
-
|
| 1527 |
-
— *end example*]
|
| 1528 |
-
|
|
|
|
| 11 |
requires-expression
|
| 12 |
```
|
| 13 |
|
| 14 |
### Literals <a id="expr.prim.literal">[[expr.prim.literal]]</a>
|
| 15 |
|
| 16 |
+
The type of a *literal* is determined based on its form as specified in
|
| 17 |
+
[[lex.literal]]. A *string-literal* is an lvalue designating a
|
| 18 |
+
corresponding string literal object [[lex.string]], a
|
| 19 |
+
*user-defined-literal* has the same value category as the corresponding
|
| 20 |
+
operator call expression described in [[lex.ext]], and any other
|
| 21 |
+
*literal* is a prvalue.
|
| 22 |
|
| 23 |
### This <a id="expr.prim.this">[[expr.prim.this]]</a>
|
| 24 |
|
| 25 |
+
The keyword `this` names a pointer to the object for which an implicit
|
| 26 |
+
object member function [[class.mfct.non.static]] is invoked or a
|
| 27 |
+
non-static data member’s initializer [[class.mem]] is evaluated.
|
| 28 |
+
|
| 29 |
+
The *current class* at a program point is the class associated with the
|
| 30 |
+
innermost class scope containing that point.
|
| 31 |
+
|
| 32 |
+
[*Note 1*: A *lambda-expression* does not introduce a class
|
| 33 |
+
scope. — *end note*]
|
| 34 |
|
| 35 |
If a declaration declares a member function or member function template
|
| 36 |
of a class `X`, the expression `this` is a prvalue of type “pointer to
|
| 37 |
+
*cv-qualifier-seq* `X`” wherever `X` is the current class between the
|
| 38 |
+
optional *cv-qualifier-seq* and the end of the *function-definition*,
|
| 39 |
+
*member-declarator*, or *declarator*. It shall not appear within the
|
| 40 |
+
declaration of either a static member function or an explicit object
|
| 41 |
+
member function of the current class (although its type and value
|
| 42 |
+
category are defined within such member functions as they are within an
|
| 43 |
+
implicit object member function).
|
| 44 |
|
| 45 |
+
[*Note 2*: This is because declaration matching does not occur until
|
| 46 |
the complete declarator is known. — *end note*]
|
| 47 |
|
| 48 |
+
[*Note 3*:
|
| 49 |
|
| 50 |
In a *trailing-return-type*, the class being defined is not required to
|
| 51 |
be complete for purposes of class member access [[expr.ref]]. Class
|
| 52 |
members declared later are not visible.
|
| 53 |
|
|
|
|
| 66 |
|
| 67 |
— *end note*]
|
| 68 |
|
| 69 |
Otherwise, if a *member-declarator* declares a non-static data member
|
| 70 |
[[class.mem]] of a class `X`, the expression `this` is a prvalue of type
|
| 71 |
+
“pointer to `X`” wherever `X` is the current class within the optional
|
| 72 |
+
default member initializer [[class.mem]].
|
| 73 |
|
| 74 |
The expression `this` shall not appear in any other context.
|
| 75 |
|
| 76 |
[*Example 2*:
|
| 77 |
|
| 78 |
``` cpp
|
| 79 |
class Outer {
|
| 80 |
int a[sizeof(*this)]; // error: not inside a member function
|
| 81 |
+
unsigned int sz = sizeof(*this); // OK, in default member initializer
|
| 82 |
|
| 83 |
void f() {
|
| 84 |
int b[sizeof(*this)]; // OK
|
| 85 |
|
| 86 |
struct Inner {
|
|
|
|
| 93 |
— *end example*]
|
| 94 |
|
| 95 |
### Parentheses <a id="expr.prim.paren">[[expr.prim.paren]]</a>
|
| 96 |
|
| 97 |
A parenthesized expression `(E)` is a primary expression whose type,
|
| 98 |
+
result, and value category are identical to those of E. The
|
| 99 |
+
parenthesized expression can be used in exactly the same contexts as
|
| 100 |
+
those where E can be used, and with the same meaning, except as
|
| 101 |
+
otherwise indicated.
|
| 102 |
|
| 103 |
### Names <a id="expr.prim.id">[[expr.prim.id]]</a>
|
| 104 |
|
| 105 |
+
#### General <a id="expr.prim.id.general">[[expr.prim.id.general]]</a>
|
| 106 |
+
|
| 107 |
``` bnf
|
| 108 |
id-expression:
|
| 109 |
unqualified-id
|
| 110 |
qualified-id
|
| 111 |
```
|
|
|
|
| 113 |
An *id-expression* is a restricted form of a *primary-expression*.
|
| 114 |
|
| 115 |
[*Note 1*: An *id-expression* can appear after `.` and `->` operators
|
| 116 |
[[expr.ref]]. — *end note*]
|
| 117 |
|
| 118 |
+
If an *id-expression* E denotes a member M of an anonymous union
|
| 119 |
+
[[class.union.anon]] U:
|
| 120 |
+
|
| 121 |
+
- If U is a non-static data member, E refers to M as a member of the
|
| 122 |
+
lookup context of the terminal name of E (after any transformation to
|
| 123 |
+
a class member access expression [[class.mfct.non.static]]).
|
| 124 |
+
\[*Example 1*: `o.x` is interpreted as `o.u.x`, where u names the
|
| 125 |
+
anonymous union member. — *end example*]
|
| 126 |
+
- Otherwise, E is interpreted as a class member access [[expr.ref]] that
|
| 127 |
+
designates the member subobject M of the anonymous union variable for
|
| 128 |
+
U. \[*Note 2*: Under this interpretation, E no longer denotes a
|
| 129 |
+
non-static data member. — *end note*] \[*Example 2*: `N::x` is
|
| 130 |
+
interpreted as `N::u.x`, where u names the anonymous union
|
| 131 |
+
variable. — *end example*]
|
| 132 |
+
|
| 133 |
+
An *id-expression* that denotes a non-static data member or implicit
|
| 134 |
+
object member function of a class can only be used:
|
| 135 |
|
| 136 |
- as part of a class member access [[expr.ref]] in which the object
|
| 137 |
expression refers to the member’s class[^10] or a class derived from
|
| 138 |
that class, or
|
| 139 |
- to form a pointer to member [[expr.unary.op]], or
|
| 140 |
- if that *id-expression* denotes a non-static data member and it
|
| 141 |
appears in an unevaluated operand.
|
| 142 |
+
\[*Example 3*:
|
| 143 |
``` cpp
|
| 144 |
struct S {
|
| 145 |
int m;
|
| 146 |
};
|
| 147 |
int i = sizeof(S::m); // OK
|
| 148 |
int j = sizeof(S::m + 42); // OK
|
| 149 |
```
|
| 150 |
|
| 151 |
— *end example*]
|
| 152 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
For an *id-expression* that denotes an overload set, overload resolution
|
| 154 |
+
is performed to select a unique function [[over.match]], [[over.over]].
|
|
|
|
| 155 |
|
| 156 |
+
[*Note 3*:
|
| 157 |
|
| 158 |
A program cannot refer to a function with a trailing *requires-clause*
|
| 159 |
whose *constraint-expression* is not satisfied, because such functions
|
| 160 |
are never selected by overload resolution.
|
| 161 |
|
| 162 |
+
[*Example 4*:
|
| 163 |
|
| 164 |
``` cpp
|
| 165 |
template<typename T> struct A {
|
| 166 |
static void f(int) requires false;
|
| 167 |
+
};
|
| 168 |
|
| 169 |
void g() {
|
| 170 |
A<int>::f(0); // error: cannot call f
|
| 171 |
void (*p1)(int) = A<int>::f; // error: cannot take the address of f
|
| 172 |
decltype(A<int>::f)* p2 = nullptr; // error: the type decltype(A<int>::f) is invalid
|
| 173 |
}
|
| 174 |
```
|
| 175 |
|
| 176 |
In each case, the constraints of `f` are not satisfied. In the
|
| 177 |
declaration of `p2`, those constraints are required to be satisfied even
|
| 178 |
+
though `f` is an unevaluated operand [[term.unevaluated.operand]].
|
| 179 |
|
| 180 |
— *end example*]
|
| 181 |
|
| 182 |
— *end note*]
|
| 183 |
|
|
|
|
| 204 |
*literal-operator-id*s, see [[over.literal]]; for *template-id*s, see
|
| 205 |
[[temp.names]]. A *type-name* or *decltype-specifier* prefixed by `~`
|
| 206 |
denotes the destructor of the type so named; see [[expr.prim.id.dtor]].
|
| 207 |
Within the definition of a non-static member function, an *identifier*
|
| 208 |
that names a non-static member is transformed to a class member access
|
| 209 |
+
expression [[class.mfct.non.static]]. — *end note*]
|
| 210 |
+
|
| 211 |
+
A *component name* of an *unqualified-id* U is
|
| 212 |
+
|
| 213 |
+
- U if it is a name or
|
| 214 |
+
- the component name of the *template-id* or *type-name* of U, if any.
|
| 215 |
+
|
| 216 |
+
[*Note 2*: Other constructs that contain names to look up can have
|
| 217 |
+
several component names
|
| 218 |
+
[[expr.prim.id.qual]], [[dcl.type.simple]], [[dcl.type.elab]], [[dcl.mptr]], [[namespace.udecl]], [[temp.param]], [[temp.names]], [[temp.res]]. — *end note*]
|
| 219 |
+
|
| 220 |
+
The *terminal name* of a construct is the component name of that
|
| 221 |
+
construct that appears lexically last.
|
| 222 |
+
|
| 223 |
+
The result is the entity denoted by the *unqualified-id*
|
| 224 |
+
[[basic.lookup.unqual]]. If the *unqualified-id* appears in a
|
| 225 |
+
*lambda-expression* at program point P and the entity is a local entity
|
| 226 |
+
[[basic.pre]] or a variable declared by an *init-capture*
|
| 227 |
+
[[expr.prim.lambda.capture]], then let S be the *compound-statement* of
|
| 228 |
+
the innermost enclosing *lambda-expression* of P. If naming the entity
|
| 229 |
+
from outside of an unevaluated operand within S would refer to an entity
|
| 230 |
+
captured by copy in some intervening *lambda-expression*, then let E be
|
| 231 |
+
the innermost such *lambda-expression*.
|
| 232 |
+
|
| 233 |
+
- If there is such a *lambda-expression* and if P is in E’s function
|
| 234 |
+
parameter scope but not its *parameter-declaration-clause*, then the
|
| 235 |
+
type of the expression is the type of a class member access expression
|
| 236 |
+
[[expr.ref]] naming the non-static data member that would be declared
|
| 237 |
+
for such a capture in the object parameter [[dcl.fct]] of the function
|
| 238 |
+
call operator of E. \[*Note 3*: If E is not declared `mutable`, the
|
| 239 |
type of such an identifier will typically be `const`
|
| 240 |
qualified. — *end note*]
|
| 241 |
+
- Otherwise (if there is no such *lambda-expression* or if P either
|
| 242 |
+
precedes E’s function parameter scope or is in E’s
|
| 243 |
+
*parameter-declaration-clause*), the type of the expression is the
|
| 244 |
+
type of the result.
|
| 245 |
|
| 246 |
+
[*Note 4*: If the entity is a template parameter object for a template
|
|
|
|
|
|
|
| 247 |
parameter of type `T` [[temp.param]], the type of the expression is
|
| 248 |
`const T`. — *end note*]
|
| 249 |
|
| 250 |
+
[*Note 5*: The type will be adjusted as described in [[expr.type]] if
|
| 251 |
it is cv-qualified or is a reference type. — *end note*]
|
| 252 |
|
| 253 |
+
The expression is an xvalue if it is move-eligible (see below); an
|
| 254 |
+
lvalue if the entity is a function, variable, structured binding
|
| 255 |
+
[[dcl.struct.bind]], data member, or template parameter object; and a
|
| 256 |
+
prvalue otherwise [[basic.lval]]; it is a bit-field if the identifier
|
| 257 |
+
designates a bit-field.
|
| 258 |
|
| 259 |
[*Example 1*:
|
| 260 |
|
| 261 |
``` cpp
|
| 262 |
void f() {
|
| 263 |
float x, &r = x;
|
| 264 |
+
|
| 265 |
+
[=]() -> decltype((x)) { // lambda returns float const& because this lambda is not mutable and
|
| 266 |
+
// x is an lvalue
|
| 267 |
decltype(x) y1; // y1 has type float
|
| 268 |
+
decltype((x)) y2 = y1; // y2 has type float const&
|
|
|
|
| 269 |
decltype(r) r1 = y1; // r1 has type float&
|
| 270 |
decltype((r)) r2 = y2; // r2 has type float const&
|
| 271 |
+
return y2;
|
| 272 |
+
};
|
| 273 |
+
|
| 274 |
+
[=](decltype((x)) y) {
|
| 275 |
+
decltype((x)) z = x; // OK, y has type float&, z has type float const&
|
| 276 |
+
};
|
| 277 |
+
|
| 278 |
+
[=] {
|
| 279 |
+
[](decltype((x)) y) {}; // OK, lambda takes a parameter of type float const&
|
| 280 |
+
|
| 281 |
+
[x=1](decltype((x)) y) {
|
| 282 |
+
decltype((x)) z = x; // OK, y has type int&, z has type int const&
|
| 283 |
+
};
|
| 284 |
};
|
| 285 |
}
|
| 286 |
```
|
| 287 |
|
| 288 |
— *end example*]
|
| 289 |
|
| 290 |
+
An *implicitly movable entity* is a variable of automatic storage
|
| 291 |
+
duration that is either a non-volatile object or an rvalue reference to
|
| 292 |
+
a non-volatile object type. In the following contexts, an
|
| 293 |
+
*id-expression* is *move-eligible*:
|
| 294 |
+
|
| 295 |
+
- If the *id-expression* (possibly parenthesized) is the operand of a
|
| 296 |
+
`return` [[stmt.return]] or `co_return` [[stmt.return.coroutine]]
|
| 297 |
+
statement, and names an implicitly movable entity declared in the body
|
| 298 |
+
or *parameter-declaration-clause* of the innermost enclosing function
|
| 299 |
+
or *lambda-expression*, or
|
| 300 |
+
- if the *id-expression* (possibly parenthesized) is the operand of a
|
| 301 |
+
*throw-expression* [[expr.throw]], and names an implicitly movable
|
| 302 |
+
entity that belongs to a scope that does not contain the
|
| 303 |
+
*compound-statement* of the innermost *lambda-expression*,
|
| 304 |
+
*try-block*, or *function-try-block* (if any) whose
|
| 305 |
+
*compound-statement* or *ctor-initializer* contains the
|
| 306 |
+
*throw-expression*.
|
| 307 |
+
|
| 308 |
#### Qualified names <a id="expr.prim.id.qual">[[expr.prim.id.qual]]</a>
|
| 309 |
|
| 310 |
``` bnf
|
| 311 |
qualified-id:
|
| 312 |
nested-name-specifier templateₒₚₜ unqualified-id
|
|
|
|
| 320 |
decltype-specifier '::'
|
| 321 |
nested-name-specifier identifier '::'
|
| 322 |
nested-name-specifier templateₒₚₜ simple-template-id '::'
|
| 323 |
```
|
| 324 |
|
| 325 |
+
The component names of a *qualified-id* are those of its
|
| 326 |
+
*nested-name-specifier* and *unqualified-id*. The component names of a
|
| 327 |
+
*nested-name-specifier* are its *identifier* (if any) and those of its
|
| 328 |
+
*type-name*, *namespace-name*, *simple-template-id*, and/or
|
| 329 |
+
*nested-name-specifier*.
|
| 330 |
+
|
| 331 |
+
A *nested-name-specifier* is *declarative* if it is part of
|
| 332 |
+
|
| 333 |
+
- a *class-head-name*,
|
| 334 |
+
- an *enum-head-name*,
|
| 335 |
+
- a *qualified-id* that is the *id-expression* of a *declarator-id*, or
|
| 336 |
+
- a declarative *nested-name-specifier*.
|
| 337 |
+
|
| 338 |
+
A declarative *nested-name-specifier* shall not have a
|
| 339 |
+
*decltype-specifier*. A declaration that uses a declarative
|
| 340 |
+
*nested-name-specifier* shall be a friend declaration or inhabit a scope
|
| 341 |
+
that contains the entity being redeclared or specialized.
|
| 342 |
+
|
| 343 |
+
The *nested-name-specifier* `::` nominates the global namespace. A
|
| 344 |
+
*nested-name-specifier* with a *decltype-specifier* nominates the type
|
| 345 |
+
denoted by the *decltype-specifier*, which shall be a class or
|
| 346 |
+
enumeration type. If a *nested-name-specifier* N is declarative and has
|
| 347 |
+
a *simple-template-id* with a template argument list A that involves a
|
| 348 |
+
template parameter, let T be the template nominated by N without A. T
|
| 349 |
+
shall be a class template.
|
| 350 |
+
|
| 351 |
+
- If A is the template argument list [[temp.arg]] of the corresponding
|
| 352 |
+
*template-head* H [[temp.mem]], N nominates the primary template of T;
|
| 353 |
+
H shall be equivalent to the *template-head* of T [[temp.over.link]].
|
| 354 |
+
- Otherwise, N nominates the partial specialization
|
| 355 |
+
[[temp.spec.partial]] of T whose template argument list is equivalent
|
| 356 |
+
to A [[temp.over.link]]; the program is ill-formed if no such partial
|
| 357 |
+
specialization exists.
|
| 358 |
+
|
| 359 |
+
Any other *nested-name-specifier* nominates the entity denoted by its
|
| 360 |
+
*type-name*, *namespace-name*, *identifier*, or *simple-template-id*. If
|
| 361 |
+
the *nested-name-specifier* is not declarative, the entity shall not be
|
| 362 |
+
a template.
|
| 363 |
+
|
| 364 |
+
A *qualified-id* shall not be of the form *nested-name-specifier*
|
| 365 |
+
`template`ₒₚₜ `~` *decltype-specifier* nor of the form
|
| 366 |
+
*decltype-specifier* `::` `~` *type-name*.
|
| 367 |
+
|
| 368 |
+
The result of a *qualified-id* Q is the entity it denotes
|
| 369 |
+
[[basic.lookup.qual]]. The type of the expression is the type of the
|
| 370 |
+
result. The result is an lvalue if the member is
|
| 371 |
+
|
| 372 |
+
- a function other than a non-static member function,
|
| 373 |
+
- a non-static member function if Q is the operand of a unary `&`
|
| 374 |
+
operator,
|
| 375 |
+
- a variable,
|
| 376 |
+
- a structured binding [[dcl.struct.bind]], or
|
| 377 |
+
- a data member,
|
| 378 |
+
|
| 379 |
and a prvalue otherwise.
|
| 380 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 381 |
#### Destruction <a id="expr.prim.id.dtor">[[expr.prim.id.dtor]]</a>
|
| 382 |
|
| 383 |
An *id-expression* that denotes the destructor of a type `T` names the
|
| 384 |
destructor of `T` if `T` is a class type [[class.dtor]], otherwise the
|
| 385 |
*id-expression* is said to name a *pseudo-destructor*.
|
|
|
|
| 387 |
If the *id-expression* names a pseudo-destructor, `T` shall be a scalar
|
| 388 |
type and the *id-expression* shall appear as the right operand of a
|
| 389 |
class member access [[expr.ref]] that forms the *postfix-expression* of
|
| 390 |
a function call [[expr.call]].
|
| 391 |
|
| 392 |
+
[*Note 1*: Such a call ends the lifetime of the object
|
| 393 |
+
[[expr.call]], [[basic.life]]. — *end note*]
|
| 394 |
|
| 395 |
[*Example 1*:
|
| 396 |
|
| 397 |
``` cpp
|
| 398 |
struct C { };
|
|
|
|
| 409 |
|
| 410 |
— *end example*]
|
| 411 |
|
| 412 |
### Lambda expressions <a id="expr.prim.lambda">[[expr.prim.lambda]]</a>
|
| 413 |
|
| 414 |
+
#### General <a id="expr.prim.lambda.general">[[expr.prim.lambda.general]]</a>
|
| 415 |
+
|
| 416 |
``` bnf
|
| 417 |
lambda-expression:
|
| 418 |
+
lambda-introducer attribute-specifier-seqₒₚₜ lambda-declarator compound-statement
|
| 419 |
+
lambda-introducer '<' template-parameter-list '>' requires-clauseₒₚₜ attribute-specifier-seqₒₚₜ
|
| 420 |
+
lambda-declarator compound-statement
|
| 421 |
```
|
| 422 |
|
| 423 |
``` bnf
|
| 424 |
lambda-introducer:
|
| 425 |
'[' lambda-captureₒₚₜ ']'
|
| 426 |
```
|
| 427 |
|
| 428 |
``` bnf
|
| 429 |
lambda-declarator:
|
| 430 |
+
lambda-specifier-seq noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ trailing-return-typeₒₚₜ
|
| 431 |
+
noexcept-specifier attribute-specifier-seqₒₚₜ trailing-return-typeₒₚₜ
|
| 432 |
+
trailing-return-typeₒₚₜ
|
| 433 |
+
'(' parameter-declaration-clause ')' lambda-specifier-seqₒₚₜ noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ
|
| 434 |
+
trailing-return-typeₒₚₜ requires-clauseₒₚₜ
|
| 435 |
+
```
|
| 436 |
+
|
| 437 |
+
``` bnf
|
| 438 |
+
lambda-specifier:
|
| 439 |
+
consteval
|
| 440 |
+
constexpr
|
| 441 |
+
mutable
|
| 442 |
+
static
|
| 443 |
+
```
|
| 444 |
+
|
| 445 |
+
``` bnf
|
| 446 |
+
lambda-specifier-seq:
|
| 447 |
+
lambda-specifier
|
| 448 |
+
lambda-specifier lambda-specifier-seq
|
| 449 |
```
|
| 450 |
|
| 451 |
A *lambda-expression* provides a concise way to create a simple function
|
| 452 |
object.
|
| 453 |
|
|
|
|
| 467 |
*closure object*.
|
| 468 |
|
| 469 |
[*Note 1*: A closure object behaves like a function object
|
| 470 |
[[function.objects]]. — *end note*]
|
| 471 |
|
| 472 |
+
An ambiguity can arise because a *requires-clause* can end in an
|
| 473 |
+
*attribute-specifier-seq*, which collides with the
|
| 474 |
+
*attribute-specifier-seq* in *lambda-expression*. In such cases, any
|
| 475 |
+
attributes are treated as *attribute-specifier-seq* in
|
| 476 |
+
*lambda-expression*.
|
| 477 |
|
| 478 |
+
[*Note 2*: Such ambiguous cases cannot have valid semantics because the
|
| 479 |
+
constraint expression would not have type `bool`. — *end note*]
|
| 480 |
+
|
| 481 |
+
A *lambda-specifier-seq* shall contain at most one of each
|
| 482 |
+
*lambda-specifier* and shall not contain both `constexpr` and
|
| 483 |
+
`consteval`. If the *lambda-declarator* contains an explicit object
|
| 484 |
+
parameter [[dcl.fct]], then no *lambda-specifier* in the
|
| 485 |
+
*lambda-specifier-seq* shall be `mutable` or `static`. The
|
| 486 |
+
*lambda-specifier-seq* shall not contain both `mutable` and `static`. If
|
| 487 |
+
the *lambda-specifier-seq* contains `static`, there shall be no
|
| 488 |
+
*lambda-capture*.
|
| 489 |
+
|
| 490 |
+
[*Note 3*: The trailing *requires-clause* is described in
|
| 491 |
[[dcl.decl]]. — *end note*]
|
| 492 |
|
| 493 |
+
If a *lambda-declarator* does not include a
|
| 494 |
+
*parameter-declaration-clause*, it is as if `()` were inserted at the
|
| 495 |
+
start of the *lambda-declarator*. If the *lambda-declarator* does not
|
| 496 |
+
include a *trailing-return-type*, it is considered to be `-> auto`.
|
| 497 |
+
|
| 498 |
+
[*Note 4*: In that case, the return type is deduced from `return`
|
| 499 |
+
statements as described in [[dcl.spec.auto]]. — *end note*]
|
| 500 |
|
| 501 |
[*Example 2*:
|
| 502 |
|
| 503 |
``` cpp
|
| 504 |
+
auto x1 = [](int i) { return i; }; // OK, return type is int
|
| 505 |
auto x2 = []{ return { 1, 2 }; }; // error: deducing return type from braced-init-list
|
| 506 |
int j;
|
| 507 |
+
auto x3 = [&]()->auto&& { return j; }; // OK, return type is int&
|
| 508 |
```
|
| 509 |
|
| 510 |
— *end example*]
|
| 511 |
|
| 512 |
A lambda is a *generic lambda* if the *lambda-expression* has any
|
|
|
|
| 514 |
has a *template-parameter-list*.
|
| 515 |
|
| 516 |
[*Example 3*:
|
| 517 |
|
| 518 |
``` cpp
|
| 519 |
+
int i = [](int i, auto a) { return i; }(3, 4); // OK, a generic lambda
|
| 520 |
+
int j = []<class T>(T t, int i) { return i; }(3, 4); // OK, a generic lambda
|
| 521 |
```
|
| 522 |
|
| 523 |
— *end example*]
|
| 524 |
|
| 525 |
#### Closure types <a id="expr.prim.lambda.closure">[[expr.prim.lambda.closure]]</a>
|
|
|
|
| 558 |
call operator template is the *requires-clause* immediately following
|
| 559 |
`<` *template-parameter-list* `>`, if any. The trailing
|
| 560 |
*requires-clause* of the function call operator or operator template is
|
| 561 |
the *requires-clause* of the *lambda-declarator*, if any.
|
| 562 |
|
| 563 |
+
[*Note 2*: The function call operator template for a generic lambda can
|
| 564 |
+
be an abbreviated function template [[dcl.fct]]. — *end note*]
|
| 565 |
|
| 566 |
[*Example 1*:
|
| 567 |
|
| 568 |
``` cpp
|
| 569 |
auto glambda = [](auto a, auto&& b) { return a < b; };
|
| 570 |
bool b = glambda(3, 3.14); // OK
|
| 571 |
|
| 572 |
auto vglambda = [](auto printer) {
|
| 573 |
+
return [=](auto&& ... ts) { // OK, ts is a function parameter pack
|
| 574 |
printer(std::forward<decltype(ts)>(ts)...);
|
| 575 |
|
| 576 |
return [=]() {
|
| 577 |
printer(ts ...);
|
| 578 |
};
|
| 579 |
};
|
| 580 |
};
|
| 581 |
auto p = vglambda( [](auto v1, auto v2, auto v3)
|
| 582 |
{ std::cout << v1 << v2 << v3; } );
|
| 583 |
+
auto q = p(1, 'a', 3.14); // OK, outputs 1a3.14
|
| 584 |
+
q(); // OK, outputs 1a3.14
|
| 585 |
+
|
| 586 |
+
auto fact = [](this auto self, int n) -> int { // OK, explicit object parameter
|
| 587 |
+
return (n <= 1) ? 1 : n * self(n-1);
|
| 588 |
+
};
|
| 589 |
+
std::cout << fact(5); // OK, outputs 120
|
| 590 |
+
```
|
| 591 |
+
|
| 592 |
+
— *end example*]
|
| 593 |
+
|
| 594 |
+
Given a lambda with a *lambda-capture*, the type of the explicit object
|
| 595 |
+
parameter, if any, of the lambda’s function call operator (possibly
|
| 596 |
+
instantiated from a function call operator template) shall be either:
|
| 597 |
+
|
| 598 |
+
- the closure type,
|
| 599 |
+
- a class type derived from the closure type, or
|
| 600 |
+
- a reference to a possibly cv-qualified such type.
|
| 601 |
+
|
| 602 |
+
[*Example 2*:
|
| 603 |
+
|
| 604 |
+
``` cpp
|
| 605 |
+
struct C {
|
| 606 |
+
template <typename T>
|
| 607 |
+
C(T);
|
| 608 |
+
};
|
| 609 |
+
|
| 610 |
+
void func(int i) {
|
| 611 |
+
int x = [=](this auto&&) { return i; }(); // OK
|
| 612 |
+
int y = [=](this C) { return i; }(); // error
|
| 613 |
+
int z = [](this C) { return 42; }(); // OK
|
| 614 |
+
}
|
| 615 |
```
|
| 616 |
|
| 617 |
— *end example*]
|
| 618 |
|
| 619 |
+
The function call operator or operator template is a static member
|
| 620 |
+
function or static member function template [[class.static.mfct]] if the
|
| 621 |
+
*lambda-expression*’s *parameter-declaration-clause* is followed by
|
| 622 |
+
`static`. Otherwise, it is a non-static member function or member
|
| 623 |
+
function template [[class.mfct.non.static]] that is declared `const`
|
| 624 |
+
[[class.mfct.non.static]] if and only if the *lambda-expression*’s
|
| 625 |
+
*parameter-declaration-clause* is not followed by `mutable` and the
|
| 626 |
+
*lambda-declarator* does not contain an explicit object parameter. It is
|
| 627 |
neither virtual nor declared `volatile`. Any *noexcept-specifier*
|
| 628 |
specified on a *lambda-expression* applies to the corresponding function
|
| 629 |
call operator or operator template. An *attribute-specifier-seq* in a
|
| 630 |
*lambda-declarator* appertains to the type of the corresponding function
|
| 631 |
+
call operator or operator template. An *attribute-specifier-seq* in a
|
| 632 |
+
*lambda-expression* preceding a *lambda-declarator* appertains to the
|
| 633 |
+
corresponding function call operator or operator template. The function
|
| 634 |
+
call operator or any given operator template specialization is a
|
| 635 |
+
constexpr function if either the corresponding *lambda-expression*'s
|
| 636 |
+
*parameter-declaration-clause* is followed by `constexpr` or
|
| 637 |
+
`consteval`, or it is constexpr-suitable [[dcl.constexpr]]. It is an
|
| 638 |
immediate function [[dcl.constexpr]] if the corresponding
|
| 639 |
*lambda-expression*'s *parameter-declaration-clause* is followed by
|
| 640 |
`consteval`.
|
| 641 |
|
| 642 |
+
[*Example 3*:
|
|
|
|
|
|
|
|
|
|
| 643 |
|
| 644 |
``` cpp
|
| 645 |
auto ID = [](auto a) { return a; };
|
| 646 |
static_assert(ID(3) == 3); // OK
|
| 647 |
|
|
|
|
| 652 |
static_assert(ID(NonLiteral{3}).n == 3); // error
|
| 653 |
```
|
| 654 |
|
| 655 |
— *end example*]
|
| 656 |
|
| 657 |
+
[*Example 4*:
|
| 658 |
|
| 659 |
``` cpp
|
| 660 |
auto monoid = [](auto v) { return [=] { return v; }; };
|
| 661 |
auto add = [](auto m1) constexpr {
|
| 662 |
auto ret = m1();
|
|
|
|
| 681 |
static_assert(add(one)(one)() == monoid(2)()); // OK
|
| 682 |
```
|
| 683 |
|
| 684 |
— *end example*]
|
| 685 |
|
| 686 |
+
[*Note 3*:
|
| 687 |
|
| 688 |
+
The function call operator or operator template can be constrained
|
| 689 |
[[temp.constr.decl]] by a *type-constraint* [[temp.param]], a
|
| 690 |
*requires-clause* [[temp.pre]], or a trailing *requires-clause*
|
| 691 |
[[dcl.decl]].
|
| 692 |
|
| 693 |
+
[*Example 5*:
|
| 694 |
|
| 695 |
``` cpp
|
| 696 |
template <typename T> concept C1 = ...;
|
| 697 |
template <std::size_t N> concept C2 = ...;
|
| 698 |
template <typename A, typename B> concept C3 = ...;
|
|
|
|
| 713 |
*lambda-capture* whose constraints (if any) are satisfied has a
|
| 714 |
conversion function to pointer to function with C++ language linkage
|
| 715 |
[[dcl.link]] having the same parameter and return types as the closure
|
| 716 |
type’s function call operator. The conversion is to “pointer to
|
| 717 |
`noexcept` function” if the function call operator has a non-throwing
|
| 718 |
+
exception specification. If the function call operator is a static
|
| 719 |
+
member function, then the value returned by this conversion function is
|
| 720 |
+
the address of the function call operator. Otherwise, the value returned
|
| 721 |
+
by this conversion function is the address of a function `F` that, when
|
| 722 |
+
invoked, has the same effect as invoking the closure type’s function
|
| 723 |
+
call operator on a default-constructed instance of the closure type. `F`
|
| 724 |
+
is a constexpr function if the function call operator is a constexpr
|
| 725 |
+
function and is an immediate function if the function call operator is
|
| 726 |
+
an immediate function.
|
| 727 |
|
| 728 |
For a generic lambda with no *lambda-capture*, the closure type has a
|
| 729 |
conversion function template to pointer to function. The conversion
|
| 730 |
function template has the same invented template parameter list, and the
|
| 731 |
pointer to function has the same parameter types, as the function call
|
| 732 |
operator template. The return type of the pointer to function shall
|
| 733 |
behave as if it were a *decltype-specifier* denoting the return type of
|
| 734 |
the corresponding function call operator template specialization.
|
| 735 |
|
| 736 |
+
[*Note 4*:
|
| 737 |
|
| 738 |
If the generic lambda has no *trailing-return-type* or the
|
| 739 |
*trailing-return-type* contains a placeholder type, return type
|
| 740 |
deduction of the corresponding function call operator template
|
| 741 |
specialization has to be done. The corresponding specialization is that
|
|
|
|
| 767 |
};
|
| 768 |
```
|
| 769 |
|
| 770 |
— *end note*]
|
| 771 |
|
| 772 |
+
[*Example 6*:
|
| 773 |
|
| 774 |
``` cpp
|
| 775 |
void f1(int (*)(int)) { }
|
| 776 |
void f2(char (*)(int)) { }
|
| 777 |
|
|
|
|
| 783 |
|
| 784 |
auto glambda = [](auto a) { return a; };
|
| 785 |
f1(glambda); // OK
|
| 786 |
f2(glambda); // error: ID is not convertible
|
| 787 |
g(glambda); // error: ambiguous
|
| 788 |
+
h(glambda); // OK, calls #3 since it is convertible from ID
|
| 789 |
int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
|
| 790 |
```
|
| 791 |
|
| 792 |
— *end example*]
|
| 793 |
|
| 794 |
+
If the function call operator template is a static member function
|
| 795 |
+
template, then the value returned by any given specialization of this
|
| 796 |
+
conversion function template is the address of the corresponding
|
| 797 |
+
function call operator template specialization. Otherwise, the value
|
| 798 |
+
returned by any given specialization of this conversion function
|
| 799 |
+
template is the address of a function `F` that, when invoked, has the
|
| 800 |
+
same effect as invoking the generic lambda’s corresponding function call
|
| 801 |
+
operator template specialization on a default-constructed instance of
|
| 802 |
+
the closure type. `F` is a constexpr function if the corresponding
|
| 803 |
+
specialization is a constexpr function and `F` is an immediate function
|
| 804 |
+
if the function call operator template specialization is an immediate
|
| 805 |
+
function.
|
| 806 |
|
| 807 |
+
[*Note 5*: This will result in the implicit instantiation of the
|
| 808 |
generic lambda’s body. The instantiated generic lambda’s return type and
|
| 809 |
parameter types are required to match the return type and parameter
|
| 810 |
types of the pointer to function. — *end note*]
|
| 811 |
|
| 812 |
+
[*Example 7*:
|
| 813 |
|
| 814 |
``` cpp
|
| 815 |
auto GL = [](auto a) { std::cout << a; return a; };
|
| 816 |
+
int (*GL_int)(int) = GL; // OK, through conversion function template
|
| 817 |
+
GL_int(3); // OK, same as GL(3)
|
| 818 |
```
|
| 819 |
|
| 820 |
— *end example*]
|
| 821 |
|
| 822 |
The conversion function or conversion function template is public,
|
| 823 |
constexpr, non-virtual, non-explicit, const, and has a non-throwing
|
| 824 |
exception specification [[except.spec]].
|
| 825 |
|
| 826 |
+
[*Example 8*:
|
| 827 |
|
| 828 |
``` cpp
|
| 829 |
auto Fwd = [](int (*fp)(int), auto a) { return fp(a); };
|
| 830 |
auto C = [](auto a) { return a; };
|
| 831 |
|
|
|
|
| 837 |
```
|
| 838 |
|
| 839 |
— *end example*]
|
| 840 |
|
| 841 |
The *lambda-expression*’s *compound-statement* yields the
|
| 842 |
+
*function-body* [[dcl.fct.def]] of the function call operator, but it is
|
| 843 |
+
not within the scope of the closure type.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 844 |
|
| 845 |
+
[*Example 9*:
|
| 846 |
|
| 847 |
``` cpp
|
| 848 |
struct S1 {
|
| 849 |
int x, y;
|
| 850 |
int operator()(int);
|
|
|
|
| 869 |
constructor and a defaulted move constructor [[class.copy.ctor]]. It has
|
| 870 |
a deleted copy assignment operator if the *lambda-expression* has a
|
| 871 |
*lambda-capture* and defaulted copy and move assignment operators
|
| 872 |
otherwise [[class.copy.assign]].
|
| 873 |
|
| 874 |
+
[*Note 6*: These special member functions are implicitly defined as
|
| 875 |
+
usual, which can result in them being defined as deleted. — *end note*]
|
| 876 |
|
| 877 |
The closure type associated with a *lambda-expression* has an
|
| 878 |
implicitly-declared destructor [[class.dtor]].
|
| 879 |
|
| 880 |
A member of a closure type shall not be explicitly instantiated
|
|
|
|
| 920 |
init-capture:
|
| 921 |
'...'ₒₚₜ identifier initializer
|
| 922 |
'&' '...'ₒₚₜ identifier initializer
|
| 923 |
```
|
| 924 |
|
| 925 |
+
The body of a *lambda-expression* may refer to local entities of
|
| 926 |
+
enclosing block scopes by capturing those entities, as described below.
|
|
|
|
| 927 |
|
| 928 |
If a *lambda-capture* includes a *capture-default* that is `&`, no
|
| 929 |
identifier in a *simple-capture* of that *lambda-capture* shall be
|
| 930 |
preceded by `&`. If a *lambda-capture* includes a *capture-default* that
|
| 931 |
is `=`, each *simple-capture* of that *lambda-capture* shall be of the
|
|
|
|
| 958 |
*simple-capture* in its *lambda-introducer* unless its innermost
|
| 959 |
enclosing scope is a block scope [[basic.scope.block]] or it appears
|
| 960 |
within a default member initializer and its innermost enclosing scope is
|
| 961 |
the corresponding class scope [[basic.scope.class]].
|
| 962 |
|
| 963 |
+
The *identifier* in a *simple-capture* shall denote a local entity
|
| 964 |
+
[[basic.lookup.unqual]], [[basic.pre]]. The *simple-capture*s `this` and
|
|
|
|
| 965 |
`* this` denote the local entity `*this`. An entity that is designated
|
| 966 |
by a *simple-capture* is said to be *explicitly captured*.
|
| 967 |
|
| 968 |
+
If an *identifier* in a *capture* appears as the *declarator-id* of a
|
| 969 |
+
parameter of the *lambda-declarator*’s *parameter-declaration-clause* or
|
| 970 |
+
as the name of a template parameter of the *lambda-expression*’s
|
| 971 |
+
*template-parameter-list*, the program is ill-formed.
|
| 972 |
|
| 973 |
[*Example 2*:
|
| 974 |
|
| 975 |
``` cpp
|
| 976 |
void f() {
|
| 977 |
int x = 0;
|
| 978 |
+
auto g = [x](int x) { return 0; }; // error: parameter and capture have the same name
|
| 979 |
+
auto h = [y = 0]<typename y>(y) { return 0; }; // error: template parameter and capture
|
| 980 |
+
// have the same name
|
| 981 |
}
|
| 982 |
```
|
| 983 |
|
| 984 |
— *end example*]
|
| 985 |
|
| 986 |
+
An *init-capture* inhabits the lambda scope [[basic.scope.lambda]] of
|
| 987 |
+
the *lambda-expression*. An *init-capture* without ellipsis behaves as
|
| 988 |
+
if it declares and explicitly captures a variable of the form “`auto`
|
| 989 |
+
*init-capture* `;`”, except that:
|
| 990 |
|
| 991 |
- if the capture is by copy (see below), the non-static data member
|
| 992 |
declared for the capture and the variable are treated as two different
|
| 993 |
ways of referring to the same object, which has the lifetime of the
|
| 994 |
non-static data member, and no additional copy and destruction is
|
|
|
|
| 1007 |
auto y = [&r = x, x = x+1]()->int {
|
| 1008 |
r += 2;
|
| 1009 |
return x+2;
|
| 1010 |
}(); // Updates ::x to 6, and initializes y to 7.
|
| 1011 |
|
| 1012 |
+
auto z = [a = 42](int a) { return 1; }; // error: parameter and conceptual local variable have the same name
|
| 1013 |
+
auto counter = [i=0]() mutable -> decltype(i) { // OK, returns int
|
| 1014 |
+
return i++;
|
| 1015 |
+
};
|
| 1016 |
```
|
| 1017 |
|
| 1018 |
— *end example*]
|
| 1019 |
|
| 1020 |
For the purposes of lambda capture, an expression potentially references
|
|
|
|
| 1028 |
*id-expression*. — *end note*]
|
| 1029 |
- A `this` expression potentially references `*this`.
|
| 1030 |
- A *lambda-expression* potentially references the local entities named
|
| 1031 |
by its *simple-capture*s.
|
| 1032 |
|
| 1033 |
+
If an expression potentially references a local entity within a scope in
|
| 1034 |
+
which it is odr-usable [[basic.def.odr]], and the expression would be
|
| 1035 |
+
potentially evaluated if the effect of any enclosing `typeid`
|
| 1036 |
expressions [[expr.typeid]] were ignored, the entity is said to be
|
| 1037 |
*implicitly captured* by each intervening *lambda-expression* with an
|
| 1038 |
associated *capture-default* that does not explicitly capture it. The
|
| 1039 |
implicit capture of `*this` is deprecated when the *capture-default* is
|
| 1040 |
`=`; see [[depr.capture.this]].
|
|
|
|
| 1045 |
void f(int, const int (&)[2] = {}); // #1
|
| 1046 |
void f(const int&, const int (&)[1]); // #2
|
| 1047 |
void test() {
|
| 1048 |
const int x = 17;
|
| 1049 |
auto g = [](auto a) {
|
| 1050 |
+
f(x); // OK, calls #1, does not capture x
|
| 1051 |
};
|
| 1052 |
|
| 1053 |
auto g1 = [=](auto a) {
|
| 1054 |
+
f(x); // OK, calls #1, captures x
|
| 1055 |
};
|
| 1056 |
|
| 1057 |
auto g2 = [=](auto a) {
|
| 1058 |
int selector[sizeof(a) == 1 ? 1 : 2]{};
|
| 1059 |
+
f(x, selector); // OK, captures x, can call #1 or #2
|
| 1060 |
};
|
| 1061 |
|
| 1062 |
auto g3 = [=](auto a) {
|
| 1063 |
typeid(a + x); // captures x regardless of whether a + x is an unevaluated operand
|
| 1064 |
};
|
| 1065 |
}
|
| 1066 |
```
|
| 1067 |
|
| 1068 |
+
Within `g1`, an implementation can optimize away the capture of `x` as
|
| 1069 |
it is not odr-used.
|
| 1070 |
|
| 1071 |
— *end example*]
|
| 1072 |
|
| 1073 |
[*Note 4*:
|
| 1074 |
|
| 1075 |
The set of captured entities is determined syntactically, and entities
|
| 1076 |
+
are implicitly captured even if the expression denoting a local entity
|
| 1077 |
+
is within a discarded statement [[stmt.if]].
|
| 1078 |
|
| 1079 |
[*Example 5*:
|
| 1080 |
|
| 1081 |
``` cpp
|
| 1082 |
template<bool B>
|
|
|
|
| 1092 |
— *end example*]
|
| 1093 |
|
| 1094 |
— *end note*]
|
| 1095 |
|
| 1096 |
An entity is *captured* if it is captured explicitly or implicitly. An
|
| 1097 |
+
entity captured by a *lambda-expression* is odr-used [[term.odr.use]] by
|
| 1098 |
+
the *lambda-expression*.
|
| 1099 |
|
| 1100 |
[*Note 5*: As a consequence, if a *lambda-expression* explicitly
|
| 1101 |
captures an entity that is not odr-usable, the program is ill-formed
|
| 1102 |
[[basic.def.odr]]. — *end note*]
|
| 1103 |
|
|
|
|
| 1107 |
void f1(int i) {
|
| 1108 |
int const N = 20;
|
| 1109 |
auto m1 = [=]{
|
| 1110 |
int const M = 30;
|
| 1111 |
auto m2 = [i]{
|
| 1112 |
+
int x[N][M]; // OK, N and M are not odr-used
|
| 1113 |
+
x[0][0] = i; // OK, i is explicitly captured by m2 and implicitly captured by m1
|
| 1114 |
};
|
| 1115 |
};
|
| 1116 |
struct s1 {
|
| 1117 |
int f;
|
| 1118 |
void work(int n) {
|
| 1119 |
int m = n*n;
|
| 1120 |
int j = 40;
|
| 1121 |
auto m3 = [this,m] {
|
| 1122 |
auto m4 = [&,j] { // error: j not odr-usable due to intervening lambda m3
|
| 1123 |
int x = n; // error: n is odr-used but not odr-usable due to intervening lambda m3
|
| 1124 |
+
x += m; // OK, m implicitly captured by m4 and explicitly captured by m3
|
| 1125 |
x += i; // error: i is odr-used but not odr-usable
|
| 1126 |
// due to intervening function and class scopes
|
| 1127 |
+
x += f; // OK, this captured implicitly by m4 and explicitly by m3
|
| 1128 |
};
|
| 1129 |
};
|
| 1130 |
}
|
| 1131 |
};
|
| 1132 |
}
|
|
|
|
| 1189 |
referenced function type if the entity is a reference to a function, or
|
| 1190 |
the type of the corresponding captured entity otherwise. A member of an
|
| 1191 |
anonymous union shall not be captured by copy.
|
| 1192 |
|
| 1193 |
Every *id-expression* within the *compound-statement* of a
|
| 1194 |
+
*lambda-expression* that is an odr-use [[term.odr.use]] of an entity
|
| 1195 |
captured by copy is transformed into an access to the corresponding
|
| 1196 |
unnamed data member of the closure type.
|
| 1197 |
|
| 1198 |
[*Note 7*: An *id-expression* that is not an odr-use refers to the
|
| 1199 |
original entity, never to a member of the closure type. However, such an
|
|
|
|
| 1209 |
``` cpp
|
| 1210 |
void f(const int*);
|
| 1211 |
void g() {
|
| 1212 |
const int N = 10;
|
| 1213 |
[=] {
|
| 1214 |
+
int arr[N]; // OK, not an odr-use, refers to automatic variable
|
| 1215 |
+
f(&N); // OK, causes N to be captured; &N points to
|
| 1216 |
// the corresponding member of the closure type
|
| 1217 |
};
|
| 1218 |
}
|
| 1219 |
```
|
| 1220 |
|
|
|
|
| 1262 |
|
| 1263 |
If a *lambda-expression* `m2` captures an entity and that entity is
|
| 1264 |
captured by an immediately enclosing *lambda-expression* `m1`, then
|
| 1265 |
`m2`’s capture is transformed as follows:
|
| 1266 |
|
| 1267 |
+
- If `m1` captures the entity by copy, `m2` captures the corresponding
|
| 1268 |
+
non-static data member of `m1`’s closure type; if `m1` is not
|
| 1269 |
+
`mutable`, the non-static data member is considered to be
|
| 1270 |
+
const-qualified.
|
| 1271 |
+
- If `m1` captures the entity by reference, `m2` captures the same
|
| 1272 |
entity captured by `m1`.
|
| 1273 |
|
| 1274 |
[*Example 11*:
|
| 1275 |
|
| 1276 |
The nested *lambda-expression*s and invocations below will output
|
|
|
|
| 1311 |
corresponding *lambda-expression* after the lifetime of the entity has
|
| 1312 |
ended is likely to result in undefined behavior. — *end note*]
|
| 1313 |
|
| 1314 |
A *simple-capture* containing an ellipsis is a pack expansion
|
| 1315 |
[[temp.variadic]]. An *init-capture* containing an ellipsis is a pack
|
| 1316 |
+
expansion that declares an *init-capture* pack [[temp.variadic]].
|
|
|
|
| 1317 |
|
| 1318 |
[*Example 12*:
|
| 1319 |
|
| 1320 |
``` cpp
|
| 1321 |
template<class... Args>
|
|
|
|
| 1382 |
|
| 1383 |
— *end example*]
|
| 1384 |
|
| 1385 |
### Requires expressions <a id="expr.prim.req">[[expr.prim.req]]</a>
|
| 1386 |
|
| 1387 |
+
#### General <a id="expr.prim.req.general">[[expr.prim.req.general]]</a>
|
| 1388 |
+
|
| 1389 |
A *requires-expression* provides a concise way to express requirements
|
| 1390 |
on template arguments that can be checked by name lookup
|
| 1391 |
[[basic.lookup]] or by checking properties of types and expressions.
|
| 1392 |
|
| 1393 |
``` bnf
|
|
|
|
| 1395 |
requires requirement-parameter-listₒₚₜ requirement-body
|
| 1396 |
```
|
| 1397 |
|
| 1398 |
``` bnf
|
| 1399 |
requirement-parameter-list:
|
| 1400 |
+
'(' parameter-declaration-clause ')'
|
| 1401 |
```
|
| 1402 |
|
| 1403 |
``` bnf
|
| 1404 |
requirement-body:
|
| 1405 |
'{' requirement-seq '}'
|
| 1406 |
```
|
| 1407 |
|
| 1408 |
``` bnf
|
| 1409 |
requirement-seq:
|
| 1410 |
requirement
|
| 1411 |
+
requirement requirement-seq
|
| 1412 |
```
|
| 1413 |
|
| 1414 |
``` bnf
|
| 1415 |
requirement:
|
| 1416 |
simple-requirement
|
|
|
|
| 1419 |
nested-requirement
|
| 1420 |
```
|
| 1421 |
|
| 1422 |
A *requires-expression* is a prvalue of type `bool` whose value is
|
| 1423 |
described below. Expressions appearing within a *requirement-body* are
|
| 1424 |
+
unevaluated operands [[term.unevaluated.operand]].
|
| 1425 |
|
| 1426 |
[*Example 1*:
|
| 1427 |
|
| 1428 |
A common use of *requires-expression*s is to define requirements in
|
| 1429 |
concepts such as the one below:
|
|
|
|
| 1451 |
|
| 1452 |
— *end example*]
|
| 1453 |
|
| 1454 |
A *requires-expression* may introduce local parameters using a
|
| 1455 |
*parameter-declaration-clause* [[dcl.fct]]. A local parameter of a
|
| 1456 |
+
*requires-expression* shall not have a default argument. These
|
|
|
|
|
|
|
| 1457 |
parameters have no linkage, storage, or lifetime; they are only used as
|
| 1458 |
notation for the purpose of defining *requirement*s. The
|
| 1459 |
*parameter-declaration-clause* of a *requirement-parameter-list* shall
|
| 1460 |
not terminate with an ellipsis.
|
| 1461 |
|
|
|
|
| 1468 |
};
|
| 1469 |
```
|
| 1470 |
|
| 1471 |
— *end example*]
|
| 1472 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1473 |
The substitution of template arguments into a *requires-expression* may
|
| 1474 |
result in the formation of invalid types or expressions in its
|
| 1475 |
*requirement*s or the violation of the semantic constraints of those
|
| 1476 |
*requirement*s. In such cases, the *requires-expression* evaluates to
|
| 1477 |
`false`; it does not cause the program to be ill-formed. The
|
|
|
|
| 1510 |
|
| 1511 |
A *simple-requirement* asserts the validity of an *expression*.
|
| 1512 |
|
| 1513 |
[*Note 1*: The enclosing *requires-expression* will evaluate to `false`
|
| 1514 |
if substitution of template arguments into the *expression* fails. The
|
| 1515 |
+
*expression* is an unevaluated operand
|
| 1516 |
+
[[term.unevaluated.operand]]. — *end note*]
|
| 1517 |
|
| 1518 |
[*Example 1*:
|
| 1519 |
|
| 1520 |
``` cpp
|
| 1521 |
template<typename T> concept C =
|
|
|
|
| 1550 |
template<typename T, typename T::type = 0> struct S;
|
| 1551 |
template<typename T> using Ref = T&;
|
| 1552 |
|
| 1553 |
template<typename T> concept C = requires {
|
| 1554 |
typename T::inner; // required nested member name
|
| 1555 |
+
typename S<T>; // required valid[temp.names] template-id;
|
| 1556 |
+
// fails if T::type does not exist as a type to which 0 can be implicitly converted
|
| 1557 |
typename Ref<T>; // required alias template substitution, fails if T is void
|
| 1558 |
};
|
| 1559 |
```
|
| 1560 |
|
| 1561 |
— *end example*]
|
| 1562 |
|
| 1563 |
A *type-requirement* that names a class template specialization does not
|
| 1564 |
+
require that type to be complete [[term.incomplete.type]].
|
| 1565 |
|
| 1566 |
#### Compound requirements <a id="expr.prim.req.compound">[[expr.prim.req.compound]]</a>
|
| 1567 |
|
| 1568 |
``` bnf
|
| 1569 |
compound-requirement:
|
|
|
|
| 1586 |
- If the *return-type-requirement* is present, then:
|
| 1587 |
- Substitution of template arguments (if any) into the
|
| 1588 |
*return-type-requirement* is performed.
|
| 1589 |
- The immediately-declared constraint [[temp.param]] of the
|
| 1590 |
*type-constraint* for `decltype((E))` shall be satisfied.
|
| 1591 |
+
|
| 1592 |
\[*Example 1*:
|
| 1593 |
Given concepts `C` and `D`,
|
| 1594 |
``` cpp
|
| 1595 |
requires {
|
| 1596 |
{ E1 } -> C;
|
|
|
|
| 1669 |
`D<T>` is satisfied if `sizeof(decltype (+t)) == 1`
|
| 1670 |
[[temp.constr.atomic]].
|
| 1671 |
|
| 1672 |
— *end example*]
|
| 1673 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|