- tmp/tmpt3e5_64t/{from.md → to.md} +156 -47
tmp/tmpt3e5_64t/{from.md → to.md}
RENAMED
|
@@ -6,20 +6,20 @@ id-expression:
|
|
| 6 |
qualified-id
|
| 7 |
```
|
| 8 |
|
| 9 |
An *id-expression* is a restricted form of a *primary-expression*.
|
| 10 |
|
| 11 |
-
[*Note 1*: An *id-expression* can appear after `.` and `->` operators
|
| 12 |
-
[[expr.ref]]
|
| 13 |
|
| 14 |
An *id-expression* that denotes a non-static data member or non-static
|
| 15 |
member function of a class can only be used:
|
| 16 |
|
| 17 |
-
- as part of a class member access
|
| 18 |
-
expression refers to the member’s class[^
|
| 19 |
that class, or
|
| 20 |
-
- to form a pointer to member
|
| 21 |
- if that *id-expression* denotes a non-static data member and it
|
| 22 |
appears in an unevaluated operand.
|
| 23 |
\[*Example 1*:
|
| 24 |
``` cpp
|
| 25 |
struct S {
|
|
@@ -29,99 +29,208 @@ member function of a class can only be used:
|
|
| 29 |
int j = sizeof(S::m + 42); // OK
|
| 30 |
```
|
| 31 |
|
| 32 |
— *end example*]
|
| 33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
#### Unqualified names <a id="expr.prim.id.unqual">[[expr.prim.id.unqual]]</a>
|
| 35 |
|
| 36 |
``` bnf
|
| 37 |
unqualified-id:
|
| 38 |
identifier
|
| 39 |
operator-function-id
|
| 40 |
conversion-function-id
|
| 41 |
literal-operator-id
|
| 42 |
-
'~'
|
| 43 |
'~' decltype-specifier
|
| 44 |
template-id
|
| 45 |
```
|
| 46 |
|
| 47 |
-
An *identifier* is an *id-expression*
|
| 48 |
-
declared
|
|
|
|
|
|
|
| 49 |
|
| 50 |
[*Note 1*: For *operator-function-id*s, see [[over.oper]]; for
|
| 51 |
*conversion-function-id*s, see [[class.conv.fct]]; for
|
| 52 |
*literal-operator-id*s, see [[over.literal]]; for *template-id*s, see
|
| 53 |
-
[[temp.names]]. A *
|
| 54 |
-
denotes
|
| 55 |
-
non-static member function, an *identifier*
|
| 56 |
-
member is transformed to a class member access
|
| 57 |
-
[[class.mfct.non-static]]). — *end note*]
|
| 58 |
-
|
| 59 |
-
The
|
| 60 |
-
|
| 61 |
-
the
|
| 62 |
-
|
| 63 |
-
[[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
|
| 65 |
#### Qualified names <a id="expr.prim.id.qual">[[expr.prim.id.qual]]</a>
|
| 66 |
|
| 67 |
``` bnf
|
| 68 |
qualified-id:
|
| 69 |
-
nested-name-specifier
|
| 70 |
```
|
| 71 |
|
| 72 |
``` bnf
|
| 73 |
nested-name-specifier:
|
| 74 |
'::'
|
| 75 |
type-name '::'
|
| 76 |
namespace-name '::'
|
| 77 |
decltype-specifier '::'
|
| 78 |
nested-name-specifier identifier '::'
|
| 79 |
-
nested-name-specifier
|
| 80 |
```
|
| 81 |
|
| 82 |
The type denoted by a *decltype-specifier* in a *nested-name-specifier*
|
| 83 |
shall be a class or enumeration type.
|
| 84 |
|
| 85 |
A *nested-name-specifier* that denotes a class, optionally followed by
|
| 86 |
-
the keyword `template`
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
|
| 94 |
[*Note 1*: A class member can be referred to using a *qualified-id* at
|
| 95 |
-
any point in its potential scope
|
| 96 |
-
[[basic.scope.class]]). — *end note*]
|
| 97 |
|
| 98 |
-
Where *
|
| 99 |
-
|
| 100 |
-
[[
|
| 101 |
-
|
| 102 |
-
*
|
| 103 |
-
|
| 104 |
-
[*Note 2*: A *typedef-name* that names a class is a *class-name* (
|
| 105 |
-
[[class.name]]). — *end note*]
|
| 106 |
|
| 107 |
The *nested-name-specifier* `::` names the global namespace. A
|
| 108 |
-
*nested-name-specifier* that names a namespace
|
| 109 |
-
optionally followed by the keyword `template`
|
| 110 |
-
|
| 111 |
-
|
| 112 |
*qualified-id*; [[namespace.qual]] describes name lookup for namespace
|
| 113 |
members that appear in *qualified-id*s. The result is the member. The
|
| 114 |
type of the result is the type of the member. The result is an lvalue if
|
| 115 |
-
the member is a function
|
|
|
|
| 116 |
|
| 117 |
-
A *nested-name-specifier* that denotes an enumeration
|
| 118 |
followed by the name of an enumerator of that enumeration, is a
|
| 119 |
*qualified-id* that refers to the enumerator. The result is the
|
| 120 |
enumerator. The type of the result is the type of the enumeration. The
|
| 121 |
result is a prvalue.
|
| 122 |
|
| 123 |
In a *qualified-id*, if the *unqualified-id* is a
|
| 124 |
-
*conversion-function-id*, its *conversion-type-id*
|
| 125 |
-
|
| 126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 127 |
|
|
|
|
| 6 |
qualified-id
|
| 7 |
```
|
| 8 |
|
| 9 |
An *id-expression* is a restricted form of a *primary-expression*.
|
| 10 |
|
| 11 |
+
[*Note 1*: An *id-expression* can appear after `.` and `->` operators
|
| 12 |
+
[[expr.ref]]. — *end note*]
|
| 13 |
|
| 14 |
An *id-expression* that denotes a non-static data member or non-static
|
| 15 |
member function of a class can only be used:
|
| 16 |
|
| 17 |
+
- as part of a class member access [[expr.ref]] in which the object
|
| 18 |
+
expression refers to the member’s class[^10] or a class derived from
|
| 19 |
that class, or
|
| 20 |
+
- to form a pointer to member [[expr.unary.op]], or
|
| 21 |
- if that *id-expression* denotes a non-static data member and it
|
| 22 |
appears in an unevaluated operand.
|
| 23 |
\[*Example 1*:
|
| 24 |
``` cpp
|
| 25 |
struct S {
|
|
|
|
| 29 |
int j = sizeof(S::m + 42); // OK
|
| 30 |
```
|
| 31 |
|
| 32 |
— *end example*]
|
| 33 |
|
| 34 |
+
A potentially-evaluated *id-expression* that denotes an immediate
|
| 35 |
+
function [[dcl.constexpr]] shall appear only
|
| 36 |
+
|
| 37 |
+
- as a subexpression of an immediate invocation, or
|
| 38 |
+
- in an immediate function context [[expr.const]].
|
| 39 |
+
|
| 40 |
+
For an *id-expression* that denotes an overload set, overload resolution
|
| 41 |
+
is performed to select a unique function ([[over.match]],
|
| 42 |
+
[[over.over]]).
|
| 43 |
+
|
| 44 |
+
[*Note 2*:
|
| 45 |
+
|
| 46 |
+
A program cannot refer to a function with a trailing *requires-clause*
|
| 47 |
+
whose *constraint-expression* is not satisfied, because such functions
|
| 48 |
+
are never selected by overload resolution.
|
| 49 |
+
|
| 50 |
+
[*Example 2*:
|
| 51 |
+
|
| 52 |
+
``` cpp
|
| 53 |
+
template<typename T> struct A {
|
| 54 |
+
static void f(int) requires false;
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
void g() {
|
| 58 |
+
A<int>::f(0); // error: cannot call f
|
| 59 |
+
void (*p1)(int) = A<int>::f; // error: cannot take the address of f
|
| 60 |
+
decltype(A<int>::f)* p2 = nullptr; // error: the type decltype(A<int>::f) is invalid
|
| 61 |
+
}
|
| 62 |
+
```
|
| 63 |
+
|
| 64 |
+
In each case, the constraints of `f` are not satisfied. In the
|
| 65 |
+
declaration of `p2`, those constraints are required to be satisfied even
|
| 66 |
+
though `f` is an unevaluated operand [[expr.prop]].
|
| 67 |
+
|
| 68 |
+
— *end example*]
|
| 69 |
+
|
| 70 |
+
— *end note*]
|
| 71 |
+
|
| 72 |
#### Unqualified names <a id="expr.prim.id.unqual">[[expr.prim.id.unqual]]</a>
|
| 73 |
|
| 74 |
``` bnf
|
| 75 |
unqualified-id:
|
| 76 |
identifier
|
| 77 |
operator-function-id
|
| 78 |
conversion-function-id
|
| 79 |
literal-operator-id
|
| 80 |
+
'~' type-name
|
| 81 |
'~' decltype-specifier
|
| 82 |
template-id
|
| 83 |
```
|
| 84 |
|
| 85 |
+
An *identifier* is only an *id-expression* if it has been suitably
|
| 86 |
+
declared [[dcl.dcl]] or if it appears as part of a *declarator-id*
|
| 87 |
+
[[dcl.decl]]. An *identifier* that names a coroutine parameter refers to
|
| 88 |
+
the copy of the parameter [[dcl.fct.def.coroutine]].
|
| 89 |
|
| 90 |
[*Note 1*: For *operator-function-id*s, see [[over.oper]]; for
|
| 91 |
*conversion-function-id*s, see [[class.conv.fct]]; for
|
| 92 |
*literal-operator-id*s, see [[over.literal]]; for *template-id*s, see
|
| 93 |
+
[[temp.names]]. A *type-name* or *decltype-specifier* prefixed by `~`
|
| 94 |
+
denotes the destructor of the type so named; see [[expr.prim.id.dtor]].
|
| 95 |
+
Within the definition of a non-static member function, an *identifier*
|
| 96 |
+
that names a non-static member is transformed to a class member access
|
| 97 |
+
expression ([[class.mfct.non-static]]). — *end note*]
|
| 98 |
+
|
| 99 |
+
The result is the entity denoted by the identifier. If the entity is a
|
| 100 |
+
local entity and naming it from outside of an unevaluated operand within
|
| 101 |
+
the declarative region where the *unqualified-id* appears would result
|
| 102 |
+
in some intervening *lambda-expression* capturing it by copy
|
| 103 |
+
[[expr.prim.lambda.capture]], the type of the expression is the type of
|
| 104 |
+
a class member access expression [[expr.ref]] naming the non-static data
|
| 105 |
+
member that would be declared for such a capture in the closure object
|
| 106 |
+
of the innermost such intervening *lambda-expression*.
|
| 107 |
+
|
| 108 |
+
[*Note 2*: If that *lambda-expression* is not declared `mutable`, the
|
| 109 |
+
type of such an identifier will typically be `const`
|
| 110 |
+
qualified. — *end note*]
|
| 111 |
+
|
| 112 |
+
The type of the expression is the type of the result.
|
| 113 |
+
|
| 114 |
+
[*Note 3*: If the entity is a template parameter object for a template
|
| 115 |
+
parameter of type `T` [[temp.param]], the type of the expression is
|
| 116 |
+
`const T`. — *end note*]
|
| 117 |
+
|
| 118 |
+
[*Note 4*: The type will be adjusted as described in [[expr.type]] if
|
| 119 |
+
it is cv-qualified or is a reference type. — *end note*]
|
| 120 |
+
|
| 121 |
+
The expression is an lvalue if the entity is a function, variable,
|
| 122 |
+
structured binding [[dcl.struct.bind]], data member, or template
|
| 123 |
+
parameter object and a prvalue otherwise [[basic.lval]]; it is a
|
| 124 |
+
bit-field if the identifier designates a bit-field.
|
| 125 |
+
|
| 126 |
+
[*Example 1*:
|
| 127 |
+
|
| 128 |
+
``` cpp
|
| 129 |
+
void f() {
|
| 130 |
+
float x, &r = x;
|
| 131 |
+
[=] {
|
| 132 |
+
decltype(x) y1; // y1 has type float
|
| 133 |
+
decltype((x)) y2 = y1; // y2 has type float const& because this lambda
|
| 134 |
+
// is not mutable and x is an lvalue
|
| 135 |
+
decltype(r) r1 = y1; // r1 has type float&
|
| 136 |
+
decltype((r)) r2 = y2; // r2 has type float const&
|
| 137 |
+
};
|
| 138 |
+
}
|
| 139 |
+
```
|
| 140 |
+
|
| 141 |
+
— *end example*]
|
| 142 |
|
| 143 |
#### Qualified names <a id="expr.prim.id.qual">[[expr.prim.id.qual]]</a>
|
| 144 |
|
| 145 |
``` bnf
|
| 146 |
qualified-id:
|
| 147 |
+
nested-name-specifier templateₒₚₜ unqualified-id
|
| 148 |
```
|
| 149 |
|
| 150 |
``` bnf
|
| 151 |
nested-name-specifier:
|
| 152 |
'::'
|
| 153 |
type-name '::'
|
| 154 |
namespace-name '::'
|
| 155 |
decltype-specifier '::'
|
| 156 |
nested-name-specifier identifier '::'
|
| 157 |
+
nested-name-specifier templateₒₚₜ simple-template-id '::'
|
| 158 |
```
|
| 159 |
|
| 160 |
The type denoted by a *decltype-specifier* in a *nested-name-specifier*
|
| 161 |
shall be a class or enumeration type.
|
| 162 |
|
| 163 |
A *nested-name-specifier* that denotes a class, optionally followed by
|
| 164 |
+
the keyword `template` [[temp.names]], and then followed by the name of
|
| 165 |
+
a member of either that class [[class.mem]] or one of its base classes
|
| 166 |
+
[[class.derived]], is a *qualified-id*; [[class.qual]] describes name
|
| 167 |
+
lookup for class members that appear in *qualified-id*s. The result is
|
| 168 |
+
the member. The type of the result is the type of the member. The result
|
| 169 |
+
is an lvalue if the member is a static member function or a data member
|
| 170 |
+
and a prvalue otherwise.
|
| 171 |
|
| 172 |
[*Note 1*: A class member can be referred to using a *qualified-id* at
|
| 173 |
+
any point in its potential scope [[basic.scope.class]]. — *end note*]
|
|
|
|
| 174 |
|
| 175 |
+
Where *type-name* `::~` *type-name* is used, the two *type-name*s shall
|
| 176 |
+
refer to the same type (ignoring cv-qualifications); this notation
|
| 177 |
+
denotes the destructor of the type so named [[expr.prim.id.dtor]]. The
|
| 178 |
+
*unqualified-id* in a *qualified-id* shall not be of the form
|
| 179 |
+
`~`*decltype-specifier*.
|
|
|
|
|
|
|
|
|
|
| 180 |
|
| 181 |
The *nested-name-specifier* `::` names the global namespace. A
|
| 182 |
+
*nested-name-specifier* that names a namespace [[basic.namespace]],
|
| 183 |
+
optionally followed by the keyword `template` [[temp.names]], and then
|
| 184 |
+
followed by the name of a member of that namespace (or the name of a
|
| 185 |
+
member of a namespace made visible by a *using-directive*), is a
|
| 186 |
*qualified-id*; [[namespace.qual]] describes name lookup for namespace
|
| 187 |
members that appear in *qualified-id*s. The result is the member. The
|
| 188 |
type of the result is the type of the member. The result is an lvalue if
|
| 189 |
+
the member is a function, a variable, or a structured binding
|
| 190 |
+
[[dcl.struct.bind]] and a prvalue otherwise.
|
| 191 |
|
| 192 |
+
A *nested-name-specifier* that denotes an enumeration [[dcl.enum]],
|
| 193 |
followed by the name of an enumerator of that enumeration, is a
|
| 194 |
*qualified-id* that refers to the enumerator. The result is the
|
| 195 |
enumerator. The type of the result is the type of the enumeration. The
|
| 196 |
result is a prvalue.
|
| 197 |
|
| 198 |
In a *qualified-id*, if the *unqualified-id* is a
|
| 199 |
+
*conversion-function-id*, its *conversion-type-id* is first looked up in
|
| 200 |
+
the class denoted by the *nested-name-specifier* of the *qualified-id*
|
| 201 |
+
and the name, if found, is used. Otherwise, it is looked up in the
|
| 202 |
+
context in which the entire *qualified-id* occurs. In each of these
|
| 203 |
+
lookups, only names that denote types or templates whose specializations
|
| 204 |
+
are types are considered.
|
| 205 |
+
|
| 206 |
+
#### Destruction <a id="expr.prim.id.dtor">[[expr.prim.id.dtor]]</a>
|
| 207 |
+
|
| 208 |
+
An *id-expression* that denotes the destructor of a type `T` names the
|
| 209 |
+
destructor of `T` if `T` is a class type [[class.dtor]], otherwise the
|
| 210 |
+
*id-expression* is said to name a *pseudo-destructor*.
|
| 211 |
+
|
| 212 |
+
If the *id-expression* names a pseudo-destructor, `T` shall be a scalar
|
| 213 |
+
type and the *id-expression* shall appear as the right operand of a
|
| 214 |
+
class member access [[expr.ref]] that forms the *postfix-expression* of
|
| 215 |
+
a function call [[expr.call]].
|
| 216 |
+
|
| 217 |
+
[*Note 1*: Such a call ends the lifetime of the object ([[expr.call]],
|
| 218 |
+
[[basic.life]]). — *end note*]
|
| 219 |
+
|
| 220 |
+
[*Example 1*:
|
| 221 |
+
|
| 222 |
+
``` cpp
|
| 223 |
+
struct C { };
|
| 224 |
+
void f() {
|
| 225 |
+
C * pc = new C;
|
| 226 |
+
using C2 = C;
|
| 227 |
+
pc->C::~C2(); // OK, destroys *pc
|
| 228 |
+
C().C::~C(); // undefined behavior: temporary of type C destroyed twice
|
| 229 |
+
using T = int;
|
| 230 |
+
0 .T::~T(); // OK, no effect
|
| 231 |
+
0.T::~T(); // error: 0.T is a user-defined-floating-point-literal[lex.ext]
|
| 232 |
+
}
|
| 233 |
+
```
|
| 234 |
+
|
| 235 |
+
— *end example*]
|
| 236 |
|