From Jason Turner

[expr.prim.id.unqual]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpw2w3k1rr/{from.md → to.md} +76 -23
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 ([[class.mfct.non-static]]). — *end note*]
27
-
28
- The result is the entity denoted by the identifier. If the entity is a
29
- local entity and naming it from outside of an unevaluated operand within
30
- the declarative region where the *unqualified-id* appears would result
31
- in some intervening *lambda-expression* capturing it by copy
32
- [[expr.prim.lambda.capture]], the type of the expression is the type of
33
- a class member access expression [[expr.ref]] naming the non-static data
34
- member that would be declared for such a capture in the closure object
35
- of the innermost such intervening *lambda-expression*.
36
-
37
- [*Note 2*: If that *lambda-expression* is not declared `mutable`, the
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  type of such an identifier will typically be `const`
39
  qualified. — *end note*]
 
 
 
 
40
 
41
- The type of the expression is the type of the result.
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 4*: The type will be adjusted as described in [[expr.type]] if
48
  it is cv-qualified or is a reference type. — *end note*]
49
 
50
- The expression is an lvalue if the entity is a function, variable,
51
- structured binding [[dcl.struct.bind]], data member, or template
52
- parameter object and a prvalue otherwise [[basic.lval]]; it is a
53
- bit-field if the identifier designates a bit-field.
 
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& because this lambda
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
+