From Jason Turner

[expr.prim.id]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpwxw7xb8w/{from.md → to.md} +312 -95
tmp/tmpwxw7xb8w/{from.md → to.md} RENAMED
@@ -4,62 +4,104 @@
4
 
5
  ``` bnf
6
  id-expression:
7
  unqualified-id
8
  qualified-id
 
9
  ```
10
 
11
  An *id-expression* is a restricted form of a *primary-expression*.
12
 
13
  [*Note 1*: An *id-expression* can appear after `.` and `->` operators
14
  [[expr.ref]]. — *end note*]
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  If an *id-expression* E denotes a member M of an anonymous union
17
  [[class.union.anon]] U:
18
 
19
  - If U is a non-static data member, E refers to M as a member of the
20
- lookup context of the terminal name of E (after any transformation to
21
- a class member access expression [[class.mfct.non.static]]).
22
- \[*Example 1*: `o.x` is interpreted as `o.u.x`, where u names the
23
  anonymous union member. — *end example*]
24
  - Otherwise, E is interpreted as a class member access [[expr.ref]] that
25
  designates the member subobject M of the anonymous union variable for
26
- U. \[*Note 2*: Under this interpretation, E no longer denotes a
27
- non-static data member. — *end note*] \[*Example 2*: `N::x` is
28
  interpreted as `N::u.x`, where u names the anonymous union
29
  variable. — *end example*]
30
 
31
- An *id-expression* that denotes a non-static data member or implicit
32
- object member function of a class can only be used:
 
33
 
34
- - as part of a class member access [[expr.ref]] in which the object
35
- expression refers to the member’s class[^10] or a class derived from
36
- that class, or
37
  - to form a pointer to member [[expr.unary.op]], or
38
- - if that *id-expression* denotes a non-static data member and it
39
- appears in an unevaluated operand.
40
- \[*Example 3*:
41
  ``` cpp
42
  struct S {
43
  int m;
44
  };
45
  int i = sizeof(S::m); // OK
46
  int j = sizeof(S::m + 42); // OK
 
47
  ```
48
 
49
  — *end example*]
50
 
51
  For an *id-expression* that denotes an overload set, overload resolution
52
  is performed to select a unique function [[over.match]], [[over.over]].
53
 
54
- [*Note 3*:
55
 
56
  A program cannot refer to a function with a trailing *requires-clause*
57
  whose *constraint-expression* is not satisfied, because such functions
58
  are never selected by overload resolution.
59
 
60
- [*Example 4*:
61
 
62
  ``` cpp
63
  template<typename T> struct A {
64
  static void f(int) requires false;
65
  };
@@ -70,12 +112,12 @@ void g() {
70
  decltype(A<int>::f)* p2 = nullptr; // error: the type decltype(A<int>::f) is invalid
71
  }
72
  ```
73
 
74
  In each case, the constraints of `f` are not satisfied. In the
75
- declaration of `p2`, those constraints are required to be satisfied even
76
- though `f` is an unevaluated operand [[term.unevaluated.operand]].
77
 
78
  — *end example*]
79
 
80
  — *end note*]
81
 
@@ -86,27 +128,24 @@ unqualified-id:
86
  identifier
87
  operator-function-id
88
  conversion-function-id
89
  literal-operator-id
90
  '~' type-name
91
- '~' decltype-specifier
92
  template-id
93
  ```
94
 
95
  An *identifier* is only an *id-expression* if it has been suitably
96
- declared [[dcl.dcl]] or if it appears as part of a *declarator-id*
97
- [[dcl.decl]]. An *identifier* that names a coroutine parameter refers to
98
- the copy of the parameter [[dcl.fct.def.coroutine]].
99
 
100
  [*Note 1*: For *operator-function-id*s, see  [[over.oper]]; for
101
  *conversion-function-id*s, see  [[class.conv.fct]]; for
102
  *literal-operator-id*s, see  [[over.literal]]; for *template-id*s, see 
103
- [[temp.names]]. A *type-name* or *decltype-specifier* prefixed by `~`
104
- denotes the destructor of the type so named; see  [[expr.prim.id.dtor]].
105
- Within the definition of a non-static member function, an *identifier*
106
- that names a non-static member is transformed to a class member access
107
- expression [[class.mfct.non.static]]. — *end note*]
108
 
109
  A *component name* of an *unqualified-id* U is
110
 
111
  - U if it is a name or
112
  - the component name of the *template-id* or *type-name* of U, if any.
@@ -117,46 +156,147 @@ several component names
117
 
118
  The *terminal name* of a construct is the component name of that
119
  construct that appears lexically last.
120
 
121
  The result is the entity denoted by the *unqualified-id*
122
- [[basic.lookup.unqual]]. If the *unqualified-id* appears in a
123
- *lambda-expression* at program point P and the entity is a local entity
124
- [[basic.pre]] or a variable declared by an *init-capture*
125
- [[expr.prim.lambda.capture]], then let S be the *compound-statement* of
126
- the innermost enclosing *lambda-expression* of P. If naming the entity
127
- from outside of an unevaluated operand within S would refer to an entity
128
- captured by copy in some intervening *lambda-expression*, then let E be
129
- the innermost such *lambda-expression*.
130
-
131
- - If there is such a *lambda-expression* and if P is in E’s function
132
- parameter scope but not its *parameter-declaration-clause*, then the
133
- type of the expression is the type of a class member access expression
134
- [[expr.ref]] naming the non-static data member that would be declared
135
- for such a capture in the object parameter [[dcl.fct]] of the function
136
- call operator of E. \[*Note 3*: If E is not declared `mutable`, the
137
- type of such an identifier will typically be `const`
138
- qualified. *end note*]
139
- - Otherwise (if there is no such *lambda-expression* or if P either
140
- precedes E’s function parameter scope or is in E’s
141
- *parameter-declaration-clause*), the type of the expression is the
142
- type of the result.
143
-
144
- [*Note 4*: If the entity is a template parameter object for a template
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  parameter of type `T` [[temp.param]], the type of the expression is
146
- `const T`. — *end note*]
147
 
148
- [*Note 5*: The type will be adjusted as described in [[expr.type]] if
 
 
 
149
  it is cv-qualified or is a reference type. — *end note*]
150
 
151
  The expression is an xvalue if it is move-eligible (see below); an
152
  lvalue if the entity is a function, variable, structured binding
153
- [[dcl.struct.bind]], data member, or template parameter object; and a
154
- prvalue otherwise [[basic.lval]]; it is a bit-field if the identifier
155
- designates a bit-field.
156
 
157
- [*Example 1*:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
 
159
  ``` cpp
160
  void f() {
161
  float x, &r = x;
162
 
@@ -183,27 +323,23 @@ void f() {
183
  }
184
  ```
185
 
186
  — *end example*]
187
 
188
- An *implicitly movable entity* is a variable of automatic storage
189
  duration that is either a non-volatile object or an rvalue reference to
190
- a non-volatile object type. In the following contexts, an
191
- *id-expression* is *move-eligible*:
192
 
193
- - If the *id-expression* (possibly parenthesized) is the operand of a
194
- `return` [[stmt.return]] or `co_return` [[stmt.return.coroutine]]
195
- statement, and names an implicitly movable entity declared in the body
196
- or *parameter-declaration-clause* of the innermost enclosing function
197
- or *lambda-expression*, or
198
- - if the *id-expression* (possibly parenthesized) is the operand of a
199
- *throw-expression* [[expr.throw]], and names an implicitly movable
200
- entity that belongs to a scope that does not contain the
201
- *compound-statement* of the innermost *lambda-expression*,
202
- *try-block*, or *function-try-block* (if any) whose
203
- *compound-statement* or *ctor-initializer* contains the
204
- *throw-expression*.
205
 
206
  #### Qualified names <a id="expr.prim.id.qual">[[expr.prim.id.qual]]</a>
207
 
208
  ``` bnf
209
  qualified-id:
@@ -213,71 +349,152 @@ qualified-id:
213
  ``` bnf
214
  nested-name-specifier:
215
  '::'
216
  type-name '::'
217
  namespace-name '::'
218
- decltype-specifier '::'
 
219
  nested-name-specifier identifier '::'
220
  nested-name-specifier templateₒₚₜ simple-template-id '::'
221
  ```
222
 
 
 
 
 
 
 
223
  The component names of a *qualified-id* are those of its
224
  *nested-name-specifier* and *unqualified-id*. The component names of a
225
  *nested-name-specifier* are its *identifier* (if any) and those of its
226
  *type-name*, *namespace-name*, *simple-template-id*, and/or
227
  *nested-name-specifier*.
228
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  A *nested-name-specifier* is *declarative* if it is part of
230
 
231
  - a *class-head-name*,
232
  - an *enum-head-name*,
233
  - a *qualified-id* that is the *id-expression* of a *declarator-id*, or
234
  - a declarative *nested-name-specifier*.
235
 
236
  A declarative *nested-name-specifier* shall not have a
237
- *decltype-specifier*. A declaration that uses a declarative
238
- *nested-name-specifier* shall be a friend declaration or inhabit a scope
239
- that contains the entity being redeclared or specialized.
 
240
 
241
- The *nested-name-specifier* `::` nominates the global namespace. A
242
- *nested-name-specifier* with a *decltype-specifier* nominates the type
243
- denoted by the *decltype-specifier*, which shall be a class or
244
- enumeration type. If a *nested-name-specifier* N is declarative and has
245
- a *simple-template-id* with a template argument list A that involves a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  template parameter, let T be the template nominated by N without A. T
247
  shall be a class template.
248
-
249
  - If A is the template argument list [[temp.arg]] of the corresponding
250
- *template-head* H [[temp.mem]], N nominates the primary template of T;
251
- H shall be equivalent to the *template-head* of T [[temp.over.link]].
252
- - Otherwise, N nominates the partial specialization
253
- [[temp.spec.partial]] of T whose template argument list is equivalent
254
- to A [[temp.over.link]]; the program is ill-formed if no such partial
255
- specialization exists.
256
-
257
- Any other *nested-name-specifier* nominates the entity denoted by its
258
- *type-name*, *namespace-name*, *identifier*, or *simple-template-id*. If
259
- the *nested-name-specifier* is not declarative, the entity shall not be
260
- a template.
261
 
262
  A *qualified-id* shall not be of the form *nested-name-specifier*
263
- `template`ₒₚₜ `~` *decltype-specifier* nor of the form
264
- *decltype-specifier* `::` `~` *type-name*.
265
 
266
  The result of a *qualified-id* Q is the entity it denotes
267
- [[basic.lookup.qual]]. The type of the expression is the type of the
268
- result. The result is an lvalue if the member is
 
 
 
 
 
 
 
 
 
 
 
 
 
269
 
270
  - a function other than a non-static member function,
271
  - a non-static member function if Q is the operand of a unary `&`
272
  operator,
273
  - a variable,
274
  - a structured binding [[dcl.struct.bind]], or
275
  - a data member,
276
 
277
  and a prvalue otherwise.
278
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  #### Destruction <a id="expr.prim.id.dtor">[[expr.prim.id.dtor]]</a>
280
 
281
  An *id-expression* that denotes the destructor of a type `T` names the
282
  destructor of `T` if `T` is a class type [[class.dtor]], otherwise the
283
  *id-expression* is said to name a *pseudo-destructor*.
 
4
 
5
  ``` bnf
6
  id-expression:
7
  unqualified-id
8
  qualified-id
9
+ pack-index-expression
10
  ```
11
 
12
  An *id-expression* is a restricted form of a *primary-expression*.
13
 
14
  [*Note 1*: An *id-expression* can appear after `.` and `->` operators
15
  [[expr.ref]]. — *end note*]
16
 
17
+ If an *id-expression* E denotes a non-static non-type member of some
18
+ class `C` at a point where the current class [[expr.prim.this]] is `X`
19
+ and
20
+
21
+ - E is potentially evaluated or `C` is `X` or a base class of `X`, and
22
+ - E is not the *id-expression* of a class member access expression
23
+ [[expr.ref]], and
24
+ - E is not the *id-expression* of a *reflect-expression*
25
+ [[expr.reflect]], and
26
+ - if E is a *qualified-id*, E is not the un-parenthesized operand of the
27
+ unary `&` operator [[expr.unary.op]],
28
+
29
+ the *id-expression* is transformed into a class member access expression
30
+ using `(*this)` as the object expression. If this transformation occurs
31
+ in the predicate of a precondition assertion of a constructor of `X` or
32
+ a postcondition assertion of a destructor of `X`, the expression is
33
+ ill-formed.
34
+
35
+ [*Note 2*: If `C` is not `X` or a base class of `X`, the class member
36
+ access expression is ill-formed. Also, if the *id-expression* occurs
37
+ within a static or explicit object member function, the class member
38
+ access is ill-formed. — *end note*]
39
+
40
+ This transformation does not apply in the template definition context
41
+ [[temp.dep.type]].
42
+
43
+ [*Example 1*:
44
+
45
+ ``` cpp
46
+ struct C {
47
+ bool b;
48
+ C() pre(b) // error
49
+ pre(&this->b) // OK
50
+ pre(sizeof(b) > 0); // OK, b is not potentially evaluated.
51
+ };
52
+ ```
53
+
54
+ — *end example*]
55
+
56
  If an *id-expression* E denotes a member M of an anonymous union
57
  [[class.union.anon]] U:
58
 
59
  - If U is a non-static data member, E refers to M as a member of the
60
+ lookup context of the terminal name of E (after any implicit
61
+ transformation to a class member access expression).
62
+ \[*Example 2*: `o.x` is interpreted as `o.u.x`, where u names the
63
  anonymous union member. — *end example*]
64
  - Otherwise, E is interpreted as a class member access [[expr.ref]] that
65
  designates the member subobject M of the anonymous union variable for
66
+ U. \[*Note 3*: Under this interpretation, E no longer denotes a
67
+ non-static data member. — *end note*] \[*Example 3*: `N::x` is
68
  interpreted as `N::u.x`, where u names the anonymous union
69
  variable. — *end example*]
70
 
71
+ An *id-expression* or *splice-expression* that designates a non-static
72
+ data member or implicit object member function of a class can only be
73
+ used:
74
 
75
+ - as part of a class member access (after any implicit transformation
76
+ (see above)) in which the object expression refers to the member’s
77
+ class or a class derived from that class, or
78
  - to form a pointer to member [[expr.unary.op]], or
79
+ - if that *id-expression* or *splice-expression* designates a non-static
80
+ data member and it appears in an unevaluated operand.
81
+ \[*Example 4*:
82
  ``` cpp
83
  struct S {
84
  int m;
85
  };
86
  int i = sizeof(S::m); // OK
87
  int j = sizeof(S::m + 42); // OK
88
+ int S::*k = &[:^^S::m:]; // OK
89
  ```
90
 
91
  — *end example*]
92
 
93
  For an *id-expression* that denotes an overload set, overload resolution
94
  is performed to select a unique function [[over.match]], [[over.over]].
95
 
96
+ [*Note 4*:
97
 
98
  A program cannot refer to a function with a trailing *requires-clause*
99
  whose *constraint-expression* is not satisfied, because such functions
100
  are never selected by overload resolution.
101
 
102
+ [*Example 5*:
103
 
104
  ``` cpp
105
  template<typename T> struct A {
106
  static void f(int) requires false;
107
  };
 
112
  decltype(A<int>::f)* p2 = nullptr; // error: the type decltype(A<int>::f) is invalid
113
  }
114
  ```
115
 
116
  In each case, the constraints of `f` are not satisfied. In the
117
+ declaration of `p2`, those constraints need to be satisfied even though
118
+ `f` is an unevaluated operand [[term.unevaluated.operand]].
119
 
120
  — *end example*]
121
 
122
  — *end note*]
123
 
 
128
  identifier
129
  operator-function-id
130
  conversion-function-id
131
  literal-operator-id
132
  '~' type-name
133
+ '~' computed-type-specifier
134
  template-id
135
  ```
136
 
137
  An *identifier* is only an *id-expression* if it has been suitably
138
+ declared [[dcl]] or if it appears as part of a *declarator-id*
139
+ [[dcl.decl]].
 
140
 
141
  [*Note 1*: For *operator-function-id*s, see  [[over.oper]]; for
142
  *conversion-function-id*s, see  [[class.conv.fct]]; for
143
  *literal-operator-id*s, see  [[over.literal]]; for *template-id*s, see 
144
+ [[temp.names]]. A *type-name* or *computed-type-specifier* prefixed by
145
+ `~` denotes the destructor of the type so named; see 
146
+ [[expr.prim.id.dtor]]. *end note*]
 
 
147
 
148
  A *component name* of an *unqualified-id* U is
149
 
150
  - U if it is a name or
151
  - the component name of the *template-id* or *type-name* of U, if any.
 
156
 
157
  The *terminal name* of a construct is the component name of that
158
  construct that appears lexically last.
159
 
160
  The result is the entity denoted by the *unqualified-id*
161
+ [[basic.lookup.unqual]].
162
+
163
+ If
164
+
165
+ - the *unqualified-id* appears in a *lambda-expression* at program point
166
+ P,
167
+ - the entity is a local entity [[basic.pre]] or a variable declared by
168
+ an *init-capture* [[expr.prim.lambda.capture]],
169
+ - naming the entity within the *compound-statement* of the innermost
170
+ enclosing *lambda-expression* of P, but not in an unevaluated operand,
171
+ would refer to an entity captured by copy in some intervening
172
+ *lambda-expression*, and
173
+ - P is in the function parameter scope, but not the
174
+ *parameter-declaration-clause*, of the innermost such
175
+ *lambda-expression* E,
176
+
177
+ then the type of the expression is the type of a class member access
178
+ expression [[expr.ref]] naming the non-static data member that would be
179
+ declared for such a capture in the object parameter [[dcl.fct]] of the
180
+ function call operator of E.
181
+
182
+ [*Note 3*: If E is not declared `mutable`, the type of such an
183
+ identifier will typically be `const` qualified. *end note*]
184
+
185
+ Otherwise, if the *unqualified-id* names a coroutine parameter, the type
186
+ of the expression is that of the copy of the parameter
187
+ [[dcl.fct.def.coroutine]], and the result is that copy.
188
+
189
+ Otherwise, if the *unqualified-id* names a result binding
190
+ [[dcl.contract.res]] attached to a function with return type `U`,
191
+
192
+ - if `U` is “reference to `T`”, then the type of the expression is
193
+ `const T`;
194
+ - otherwise, the type of the expression is `const U`.
195
+
196
+ Otherwise, if the *unqualified-id* appears in the predicate of a
197
+ contract assertion C [[basic.contract]] and the entity is
198
+
199
+ - a variable declared outside of C of object type `T`,
200
+ - a variable or template parameter declared outside of C of type
201
+ “reference to `T`”, or
202
+ - a structured binding of type `T` whose corresponding variable is
203
+ declared outside of C,
204
+
205
+ then the type of the expression is `const` `T`.
206
+
207
+ [*Example 1*:
208
+
209
+ ``` cpp
210
+ int n = 0;
211
+ struct X { bool m(); };
212
+
213
+ struct Y {
214
+ int z = 0;
215
+
216
+ void f(int i, int* p, int& r, X x, X* px)
217
+ pre (++n) // error: attempting to modify const lvalue
218
+ pre (++i) // error: attempting to modify const lvalue
219
+ pre (++(*p)) // OK
220
+ pre (++r) // error: attempting to modify const lvalue
221
+ pre (x.m()) // error: calling non-const member function
222
+ pre (px->m()) // OK
223
+ pre ([=,&i,*this] mutable {
224
+ ++n; // error: attempting to modify const lvalue
225
+ ++i; // error: attempting to modify const lvalue
226
+ ++p; // OK, refers to member of closure type
227
+ ++r; // OK, refers to non-reference member of closure type
228
+ ++this->z; // OK, captured *this
229
+ ++z; // OK, captured *this
230
+ int j = 17;
231
+ [&]{
232
+ int k = 34;
233
+ ++i; // error: attempting to modify const lvalue
234
+ ++j; // OK
235
+ ++k; // OK
236
+ }();
237
+ return true;
238
+ }());
239
+
240
+ template <int N, int& R, int* P>
241
+ void g()
242
+ pre(++N) // error: attempting to modify prvalue
243
+ pre(++R) // error: attempting to modify const lvalue
244
+ pre(++(*P)); // OK
245
+
246
+ int h()
247
+ post(r : ++r) // error: attempting to modify const lvalue
248
+ post(r: [=] mutable {
249
+ ++r; // OK, refers to member of closure type
250
+ return true;
251
+ }());
252
+
253
+ int& k()
254
+ post(r : ++r); // error: attempting to modify const lvalue
255
+ };
256
+ ```
257
+
258
+ — *end example*]
259
+
260
+ Otherwise, if the entity is a template parameter object for a template
261
  parameter of type `T` [[temp.param]], the type of the expression is
262
+ `const T`.
263
 
264
+ In all other cases, the type of the expression is the type of the
265
+ entity.
266
+
267
+ [*Note 4*: The type will be adjusted as described in [[expr.type]] if
268
  it is cv-qualified or is a reference type. — *end note*]
269
 
270
  The expression is an xvalue if it is move-eligible (see below); an
271
  lvalue if the entity is a function, variable, structured binding
272
+ [[dcl.struct.bind]], result binding [[dcl.contract.res]], data member,
273
+ or template parameter object; and a prvalue otherwise [[basic.lval]]; it
274
+ is a bit-field if the identifier designates a bit-field.
275
 
276
+ If an *id-expression* E appears in the predicate of a function contract
277
+ assertion attached to a function *f* and denotes a function parameter of
278
+ *f* and the implementation introduces any temporary objects to hold the
279
+ value of that parameter as specified in [[class.temporary]],
280
+
281
+ - if the contract assertion is a precondition assertion and the
282
+ evaluation of the precondition assertion is sequenced before the
283
+ initialization of the parameter object, E refers to the most recently
284
+ initialized such temporary object, and
285
+ - if the contract assertion is a postcondition assertion, it is
286
+ unspecified whether E refers to one of the temporary objects or the
287
+ parameter object; the choice is consistent within a single evaluation
288
+ of a postcondition assertion.
289
+
290
+ If an *id-expression* E names a result binding in a postcondition
291
+ assertion and the implementation introduces any temporary objects to
292
+ hold the result object as specified in [[class.temporary]], and the
293
+ postcondition assertion is sequenced before the initialization of the
294
+ result object [[expr.call]], E refers to the most recently initialized
295
+ such temporary object.
296
+
297
+ [*Example 2*:
298
 
299
  ``` cpp
300
  void f() {
301
  float x, &r = x;
302
 
 
323
  }
324
  ```
325
 
326
  — *end example*]
327
 
328
+ An *implicitly movable entity* is a variable with automatic storage
329
  duration that is either a non-volatile object or an rvalue reference to
330
+ a non-volatile object type. An *id-expression* or *splice-expression*
331
+ [[expr.prim.splice]] is *move-eligible* if
332
 
333
+ - it designates an implicitly movable entity,
334
+ - it is the (possibly parenthesized) operand of a `return`
335
+ [[stmt.return]] or `co_return` [[stmt.return.coroutine]] statement or
336
+ of a *throw-expression* [[expr.throw]], and
337
+ - each intervening scope between the declaration of the entity and the
338
+ innermost enclosing scope of the expression is a block scope and, for
339
+ a *throw-expression*, is not the block scope of a *try-block* or
340
+ *function-try-block*.
 
 
 
 
341
 
342
  #### Qualified names <a id="expr.prim.id.qual">[[expr.prim.id.qual]]</a>
343
 
344
  ``` bnf
345
  qualified-id:
 
349
  ``` bnf
350
  nested-name-specifier:
351
  '::'
352
  type-name '::'
353
  namespace-name '::'
354
+ computed-type-specifier '::'
355
+ splice-scope-specifier '::'
356
  nested-name-specifier identifier '::'
357
  nested-name-specifier templateₒₚₜ simple-template-id '::'
358
  ```
359
 
360
+ ``` bnf
361
+ splice-scope-specifier:
362
+ splice-specifier
363
+ templateₒₚₜ splice-specialization-specifier
364
+ ```
365
+
366
  The component names of a *qualified-id* are those of its
367
  *nested-name-specifier* and *unqualified-id*. The component names of a
368
  *nested-name-specifier* are its *identifier* (if any) and those of its
369
  *type-name*, *namespace-name*, *simple-template-id*, and/or
370
  *nested-name-specifier*.
371
 
372
+ A *splice-specifier* or *splice-specialization-specifier* that is not
373
+ followed by `::` is never interpreted as part of a
374
+ *splice-scope-specifier*. The keyword `template` may only be omitted
375
+ from the form `\opt{template} splice-specialization-specifier ::` when
376
+ the *splice-specialization-specifier* is preceded by `typename`.
377
+
378
+ [*Example 1*:
379
+
380
+ ``` cpp
381
+ template<int V>
382
+ struct TCls {
383
+ static constexpr int s = V;
384
+ using type = int;
385
+ };
386
+
387
+ int v1 = [:^^TCls<1>:]::s;
388
+ int v2 = template [:^^TCls:]<2>::s; // OK, template binds to splice-scope-specifier
389
+ typename [:^^TCls:]<3>::type v3 = 3; // OK, typename binds to the qualified name
390
+ template [:^^TCls:]<3>::type v4 = 4; // OK, template binds to the splice-scope-specifier
391
+ typename template [:^^TCls:]<3>::type v5 = 5; // OK, same as v3
392
+ [:^^TCls:]<3>::type v6 = 6; // error: unexpected <
393
+ ```
394
+
395
+ — *end example*]
396
+
397
  A *nested-name-specifier* is *declarative* if it is part of
398
 
399
  - a *class-head-name*,
400
  - an *enum-head-name*,
401
  - a *qualified-id* that is the *id-expression* of a *declarator-id*, or
402
  - a declarative *nested-name-specifier*.
403
 
404
  A declarative *nested-name-specifier* shall not have a
405
+ *computed-type-specifier* or a *splice-scope-specifier*. A declaration
406
+ that uses a declarative *nested-name-specifier* shall be a friend
407
+ declaration or inhabit a scope that contains the entity being redeclared
408
+ or specialized.
409
 
410
+ The entity designated by a *nested-name-specifier* is determined as
411
+ follows:
412
+
413
+ - The *nested-name-specifier* `::` designates the global namespace.
414
+ - A *nested-name-specifier* with a *computed-type-specifier* designates
415
+ the same type designated by the *computed-type-specifier*, which shall
416
+ be a class or enumeration type.
417
+ - For a *nested-name-specifier* of the form `splice-specifier ::`, the
418
+ *splice-specifier* shall designate a class or enumeration type or a
419
+ namespace. The *nested-name-specifier* designates the same entity as
420
+ the *splice-specifier*.
421
+ - For a *nested-name-specifier* of the form
422
+ `\opt{template} splice-specialization-specifier ::`, the
423
+ *splice-specifier* of the *splice-specialization-specifier* shall
424
+ designate a class template or an alias template T. Letting S be the
425
+ specialization of T corresponding to the template argument list of the
426
+ *splice-specialization-specifier*, S shall either be a class template
427
+ specialization or an alias template specialization that denotes a
428
+ class or enumeration type. The *nested-name-specifier* designates the
429
+ underlying entity of S.
430
+ - If a *nested-name-specifier* N is declarative and has a
431
+ *simple-template-id* with a template argument list A that involves a
432
  template parameter, let T be the template nominated by N without A. T
433
  shall be a class template.
 
434
  - If A is the template argument list [[temp.arg]] of the corresponding
435
+ *template-head* H [[temp.mem]], N designates the primary template of
436
+ T; H shall be equivalent to the *template-head* of T
437
+ [[temp.over.link]].
438
+ - Otherwise, N designates the partial specialization
439
+ [[temp.spec.partial]] of T whose template argument list is
440
+ equivalent to A [[temp.over.link]]; the program is ill-formed if no
441
+ such partial specialization exists.
442
+ - Any other *nested-name-specifier* designates the entity denotes by its
443
+ *type-name*, *namespace-name*, *identifier*, or *simple-template-id*.
444
+ If the *nested-name-specifier* is not declarative, the entity shall
445
+ not be a template.
446
 
447
  A *qualified-id* shall not be of the form *nested-name-specifier*
448
+ `template`ₒₚₜ `~` *computed-type-specifier* nor of the form
449
+ *computed-type-specifier* `::` `~` *type-name*.
450
 
451
  The result of a *qualified-id* Q is the entity it denotes
452
+ [[basic.lookup.qual]].
453
+
454
+ If Q appears in the predicate of a contract assertion C
455
+ [[basic.contract]] and the entity is
456
+
457
+ - a variable declared outside of C of object type `T`,
458
+ - a variable declared outside of C of type “reference to `T`”, or
459
+ - a structured binding of type `T` whose corresponding variable is
460
+ declared outside of C,
461
+
462
+ then the type of the expression is `const` `T`.
463
+
464
+ Otherwise, the type of the expression is the type of the result.
465
+
466
+ The result is an lvalue if the member is
467
 
468
  - a function other than a non-static member function,
469
  - a non-static member function if Q is the operand of a unary `&`
470
  operator,
471
  - a variable,
472
  - a structured binding [[dcl.struct.bind]], or
473
  - a data member,
474
 
475
  and a prvalue otherwise.
476
 
477
+ #### Pack indexing expression <a id="expr.prim.pack.index">[[expr.prim.pack.index]]</a>
478
+
479
+ ``` bnf
480
+ pack-index-expression:
481
+ id-expression '...' '[' constant-expression ']'
482
+ ```
483
+
484
+ The *id-expression* P in a *pack-index-expression* shall be an
485
+ *identifier* that denotes a pack.
486
+
487
+ The *constant-expression* shall be a converted constant expression
488
+ [[expr.const]] of type `std::size_t` whose value V, termed the index, is
489
+ such that 0 ≤ V < `sizeof...($P$)`.
490
+
491
+ A *pack-index-expression* is a pack expansion [[temp.variadic]].
492
+
493
+ [*Note 1*: A *pack-index-expression* denotes the Vᵗʰ element of the
494
+ pack. — *end note*]
495
+
496
  #### Destruction <a id="expr.prim.id.dtor">[[expr.prim.id.dtor]]</a>
497
 
498
  An *id-expression* that denotes the destructor of a type `T` names the
499
  destructor of `T` if `T` is a class type [[class.dtor]], otherwise the
500
  *id-expression* is said to name a *pseudo-destructor*.