From Jason Turner

[expr.prim.id.general]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpvznap11n/{from.md → to.md} +59 -17
tmp/tmpvznap11n/{from.md → to.md} RENAMED
@@ -2,62 +2,104 @@
2
 
3
  ``` bnf
4
  id-expression:
5
  unqualified-id
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
  If an *id-expression* E denotes a member M of an anonymous union
15
  [[class.union.anon]] U:
16
 
17
  - If U is a non-static data member, E refers to M as a member of the
18
- lookup context of the terminal name of E (after any transformation to
19
- a class member access expression [[class.mfct.non.static]]).
20
- \[*Example 1*: `o.x` is interpreted as `o.u.x`, where u names the
21
  anonymous union member. — *end example*]
22
  - Otherwise, E is interpreted as a class member access [[expr.ref]] that
23
  designates the member subobject M of the anonymous union variable for
24
- U. \[*Note 2*: Under this interpretation, E no longer denotes a
25
- non-static data member. — *end note*] \[*Example 2*: `N::x` is
26
  interpreted as `N::u.x`, where u names the anonymous union
27
  variable. — *end example*]
28
 
29
- An *id-expression* that denotes a non-static data member or implicit
30
- object member function of a class can only be used:
 
31
 
32
- - as part of a class member access [[expr.ref]] in which the object
33
- expression refers to the member’s class[^10] or a class derived from
34
- that class, or
35
  - to form a pointer to member [[expr.unary.op]], or
36
- - if that *id-expression* denotes a non-static data member and it
37
- appears in an unevaluated operand.
38
- \[*Example 3*:
39
  ``` cpp
40
  struct S {
41
  int m;
42
  };
43
  int i = sizeof(S::m); // OK
44
  int j = sizeof(S::m + 42); // OK
 
45
  ```
46
 
47
  — *end example*]
48
 
49
  For an *id-expression* that denotes an overload set, overload resolution
50
  is performed to select a unique function [[over.match]], [[over.over]].
51
 
52
- [*Note 3*:
53
 
54
  A program cannot refer to a function with a trailing *requires-clause*
55
  whose *constraint-expression* is not satisfied, because such functions
56
  are never selected by overload resolution.
57
 
58
- [*Example 4*:
59
 
60
  ``` cpp
61
  template<typename T> struct A {
62
  static void f(int) requires false;
63
  };
@@ -68,12 +110,12 @@ void g() {
68
  decltype(A<int>::f)* p2 = nullptr; // error: the type decltype(A<int>::f) is invalid
69
  }
70
  ```
71
 
72
  In each case, the constraints of `f` are not satisfied. In the
73
- declaration of `p2`, those constraints are required to be satisfied even
74
- though `f` is an unevaluated operand [[term.unevaluated.operand]].
75
 
76
  — *end example*]
77
 
78
  — *end note*]
79
 
 
2
 
3
  ``` bnf
4
  id-expression:
5
  unqualified-id
6
  qualified-id
7
+ pack-index-expression
8
  ```
9
 
10
  An *id-expression* is a restricted form of a *primary-expression*.
11
 
12
  [*Note 1*: An *id-expression* can appear after `.` and `->` operators
13
  [[expr.ref]]. — *end note*]
14
 
15
+ If an *id-expression* E denotes a non-static non-type member of some
16
+ class `C` at a point where the current class [[expr.prim.this]] is `X`
17
+ and
18
+
19
+ - E is potentially evaluated or `C` is `X` or a base class of `X`, and
20
+ - E is not the *id-expression* of a class member access expression
21
+ [[expr.ref]], and
22
+ - E is not the *id-expression* of a *reflect-expression*
23
+ [[expr.reflect]], and
24
+ - if E is a *qualified-id*, E is not the un-parenthesized operand of the
25
+ unary `&` operator [[expr.unary.op]],
26
+
27
+ the *id-expression* is transformed into a class member access expression
28
+ using `(*this)` as the object expression. If this transformation occurs
29
+ in the predicate of a precondition assertion of a constructor of `X` or
30
+ a postcondition assertion of a destructor of `X`, the expression is
31
+ ill-formed.
32
+
33
+ [*Note 2*: If `C` is not `X` or a base class of `X`, the class member
34
+ access expression is ill-formed. Also, if the *id-expression* occurs
35
+ within a static or explicit object member function, the class member
36
+ access is ill-formed. — *end note*]
37
+
38
+ This transformation does not apply in the template definition context
39
+ [[temp.dep.type]].
40
+
41
+ [*Example 1*:
42
+
43
+ ``` cpp
44
+ struct C {
45
+ bool b;
46
+ C() pre(b) // error
47
+ pre(&this->b) // OK
48
+ pre(sizeof(b) > 0); // OK, b is not potentially evaluated.
49
+ };
50
+ ```
51
+
52
+ — *end example*]
53
+
54
  If an *id-expression* E denotes a member M of an anonymous union
55
  [[class.union.anon]] U:
56
 
57
  - If U is a non-static data member, E refers to M as a member of the
58
+ lookup context of the terminal name of E (after any implicit
59
+ transformation to a class member access expression).
60
+ \[*Example 2*: `o.x` is interpreted as `o.u.x`, where u names the
61
  anonymous union member. — *end example*]
62
  - Otherwise, E is interpreted as a class member access [[expr.ref]] that
63
  designates the member subobject M of the anonymous union variable for
64
+ U. \[*Note 3*: Under this interpretation, E no longer denotes a
65
+ non-static data member. — *end note*] \[*Example 3*: `N::x` is
66
  interpreted as `N::u.x`, where u names the anonymous union
67
  variable. — *end example*]
68
 
69
+ An *id-expression* or *splice-expression* that designates a non-static
70
+ data member or implicit object member function of a class can only be
71
+ used:
72
 
73
+ - as part of a class member access (after any implicit transformation
74
+ (see above)) in which the object expression refers to the member’s
75
+ class or a class derived from that class, or
76
  - to form a pointer to member [[expr.unary.op]], or
77
+ - if that *id-expression* or *splice-expression* designates a non-static
78
+ data member and it appears in an unevaluated operand.
79
+ \[*Example 4*:
80
  ``` cpp
81
  struct S {
82
  int m;
83
  };
84
  int i = sizeof(S::m); // OK
85
  int j = sizeof(S::m + 42); // OK
86
+ int S::*k = &[:^^S::m:]; // OK
87
  ```
88
 
89
  — *end example*]
90
 
91
  For an *id-expression* that denotes an overload set, overload resolution
92
  is performed to select a unique function [[over.match]], [[over.over]].
93
 
94
+ [*Note 4*:
95
 
96
  A program cannot refer to a function with a trailing *requires-clause*
97
  whose *constraint-expression* is not satisfied, because such functions
98
  are never selected by overload resolution.
99
 
100
+ [*Example 5*:
101
 
102
  ``` cpp
103
  template<typename T> struct A {
104
  static void f(int) requires false;
105
  };
 
110
  decltype(A<int>::f)* p2 = nullptr; // error: the type decltype(A<int>::f) is invalid
111
  }
112
  ```
113
 
114
  In each case, the constraints of `f` are not satisfied. In the
115
+ declaration of `p2`, those constraints need to be satisfied even though
116
+ `f` is an unevaluated operand [[term.unevaluated.operand]].
117
 
118
  — *end example*]
119
 
120
  — *end note*]
121