tmp/tmpw2w3k1rr/{from.md → to.md}
RENAMED
|
@@ -21,51 +21,104 @@ the copy of the parameter [[dcl.fct.def.coroutine]].
|
|
| 21 |
*literal-operator-id*s, see [[over.literal]]; for *template-id*s, see
|
| 22 |
[[temp.names]]. A *type-name* or *decltype-specifier* prefixed by `~`
|
| 23 |
denotes the destructor of the type so named; see [[expr.prim.id.dtor]].
|
| 24 |
Within the definition of a non-static member function, an *identifier*
|
| 25 |
that names a non-static member is transformed to a class member access
|
| 26 |
-
expression
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
type of such an identifier will typically be `const`
|
| 39 |
qualified. — *end note*]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
[*Note 3*: If the entity is a template parameter object for a template
|
| 44 |
parameter of type `T` [[temp.param]], the type of the expression is
|
| 45 |
`const T`. — *end note*]
|
| 46 |
|
| 47 |
-
[*Note
|
| 48 |
it is cv-qualified or is a reference type. — *end note*]
|
| 49 |
|
| 50 |
-
The expression is an
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
|
|
|
| 54 |
|
| 55 |
[*Example 1*:
|
| 56 |
|
| 57 |
``` cpp
|
| 58 |
void f() {
|
| 59 |
float x, &r = x;
|
| 60 |
-
|
|
|
|
|
|
|
| 61 |
decltype(x) y1; // y1 has type float
|
| 62 |
-
decltype((x)) y2 = y1; // y2 has type float const&
|
| 63 |
-
// is not mutable and x is an lvalue
|
| 64 |
decltype(r) r1 = y1; // r1 has type float&
|
| 65 |
decltype((r)) r2 = y2; // r2 has type float const&
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
};
|
| 67 |
}
|
| 68 |
```
|
| 69 |
|
| 70 |
— *end example*]
|
| 71 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
*literal-operator-id*s, see [[over.literal]]; for *template-id*s, see
|
| 22 |
[[temp.names]]. A *type-name* or *decltype-specifier* prefixed by `~`
|
| 23 |
denotes the destructor of the type so named; see [[expr.prim.id.dtor]].
|
| 24 |
Within the definition of a non-static member function, an *identifier*
|
| 25 |
that names a non-static member is transformed to a class member access
|
| 26 |
+
expression [[class.mfct.non.static]]. — *end note*]
|
| 27 |
+
|
| 28 |
+
A *component name* of an *unqualified-id* U is
|
| 29 |
+
|
| 30 |
+
- U if it is a name or
|
| 31 |
+
- the component name of the *template-id* or *type-name* of U, if any.
|
| 32 |
+
|
| 33 |
+
[*Note 2*: Other constructs that contain names to look up can have
|
| 34 |
+
several component names
|
| 35 |
+
[[expr.prim.id.qual]], [[dcl.type.simple]], [[dcl.type.elab]], [[dcl.mptr]], [[namespace.udecl]], [[temp.param]], [[temp.names]], [[temp.res]]. — *end note*]
|
| 36 |
+
|
| 37 |
+
The *terminal name* of a construct is the component name of that
|
| 38 |
+
construct that appears lexically last.
|
| 39 |
+
|
| 40 |
+
The result is the entity denoted by the *unqualified-id*
|
| 41 |
+
[[basic.lookup.unqual]]. If the *unqualified-id* appears in a
|
| 42 |
+
*lambda-expression* at program point P and the entity is a local entity
|
| 43 |
+
[[basic.pre]] or a variable declared by an *init-capture*
|
| 44 |
+
[[expr.prim.lambda.capture]], then let S be the *compound-statement* of
|
| 45 |
+
the innermost enclosing *lambda-expression* of P. If naming the entity
|
| 46 |
+
from outside of an unevaluated operand within S would refer to an entity
|
| 47 |
+
captured by copy in some intervening *lambda-expression*, then let E be
|
| 48 |
+
the innermost such *lambda-expression*.
|
| 49 |
+
|
| 50 |
+
- If there is such a *lambda-expression* and if P is in E’s function
|
| 51 |
+
parameter scope but not its *parameter-declaration-clause*, then the
|
| 52 |
+
type of the expression is the type of a class member access expression
|
| 53 |
+
[[expr.ref]] naming the non-static data member that would be declared
|
| 54 |
+
for such a capture in the object parameter [[dcl.fct]] of the function
|
| 55 |
+
call operator of E. \[*Note 3*: If E is not declared `mutable`, the
|
| 56 |
type of such an identifier will typically be `const`
|
| 57 |
qualified. — *end note*]
|
| 58 |
+
- Otherwise (if there is no such *lambda-expression* or if P either
|
| 59 |
+
precedes E’s function parameter scope or is in E’s
|
| 60 |
+
*parameter-declaration-clause*), the type of the expression is the
|
| 61 |
+
type of the result.
|
| 62 |
|
| 63 |
+
[*Note 4*: If the entity is a template parameter object for a template
|
|
|
|
|
|
|
| 64 |
parameter of type `T` [[temp.param]], the type of the expression is
|
| 65 |
`const T`. — *end note*]
|
| 66 |
|
| 67 |
+
[*Note 5*: The type will be adjusted as described in [[expr.type]] if
|
| 68 |
it is cv-qualified or is a reference type. — *end note*]
|
| 69 |
|
| 70 |
+
The expression is an xvalue if it is move-eligible (see below); an
|
| 71 |
+
lvalue if the entity is a function, variable, structured binding
|
| 72 |
+
[[dcl.struct.bind]], data member, or template parameter object; and a
|
| 73 |
+
prvalue otherwise [[basic.lval]]; it is a bit-field if the identifier
|
| 74 |
+
designates a bit-field.
|
| 75 |
|
| 76 |
[*Example 1*:
|
| 77 |
|
| 78 |
``` cpp
|
| 79 |
void f() {
|
| 80 |
float x, &r = x;
|
| 81 |
+
|
| 82 |
+
[=]() -> decltype((x)) { // lambda returns float const& because this lambda is not mutable and
|
| 83 |
+
// x is an lvalue
|
| 84 |
decltype(x) y1; // y1 has type float
|
| 85 |
+
decltype((x)) y2 = y1; // y2 has type float const&
|
|
|
|
| 86 |
decltype(r) r1 = y1; // r1 has type float&
|
| 87 |
decltype((r)) r2 = y2; // r2 has type float const&
|
| 88 |
+
return y2;
|
| 89 |
+
};
|
| 90 |
+
|
| 91 |
+
[=](decltype((x)) y) {
|
| 92 |
+
decltype((x)) z = x; // OK, y has type float&, z has type float const&
|
| 93 |
+
};
|
| 94 |
+
|
| 95 |
+
[=] {
|
| 96 |
+
[](decltype((x)) y) {}; // OK, lambda takes a parameter of type float const&
|
| 97 |
+
|
| 98 |
+
[x=1](decltype((x)) y) {
|
| 99 |
+
decltype((x)) z = x; // OK, y has type int&, z has type int const&
|
| 100 |
+
};
|
| 101 |
};
|
| 102 |
}
|
| 103 |
```
|
| 104 |
|
| 105 |
— *end example*]
|
| 106 |
|
| 107 |
+
An *implicitly movable entity* is a variable of automatic storage
|
| 108 |
+
duration that is either a non-volatile object or an rvalue reference to
|
| 109 |
+
a non-volatile object type. In the following contexts, an
|
| 110 |
+
*id-expression* is *move-eligible*:
|
| 111 |
+
|
| 112 |
+
- If the *id-expression* (possibly parenthesized) is the operand of a
|
| 113 |
+
`return` [[stmt.return]] or `co_return` [[stmt.return.coroutine]]
|
| 114 |
+
statement, and names an implicitly movable entity declared in the body
|
| 115 |
+
or *parameter-declaration-clause* of the innermost enclosing function
|
| 116 |
+
or *lambda-expression*, or
|
| 117 |
+
- if the *id-expression* (possibly parenthesized) is the operand of a
|
| 118 |
+
*throw-expression* [[expr.throw]], and names an implicitly movable
|
| 119 |
+
entity that belongs to a scope that does not contain the
|
| 120 |
+
*compound-statement* of the innermost *lambda-expression*,
|
| 121 |
+
*try-block*, or *function-try-block* (if any) whose
|
| 122 |
+
*compound-statement* or *ctor-initializer* contains the
|
| 123 |
+
*throw-expression*.
|
| 124 |
+
|