From Jason Turner

[expr.ref]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp1e38vtxc/{from.md → to.md} +110 -66
tmp/tmp1e38vtxc/{from.md → to.md} RENAMED
@@ -1,29 +1,36 @@
1
  #### Class member access <a id="expr.ref">[[expr.ref]]</a>
2
 
3
  A postfix expression followed by a dot `.` or an arrow `->`, optionally
4
  followed by the keyword `template`, and then followed by an
5
- *id-expression*, is a postfix expression. The postfix expression before
6
- the dot or arrow is evaluated;[^12]
7
 
8
- the result of that evaluation, together with the *id-expression*,
9
- determines the result of the entire postfix expression.
 
 
 
10
 
11
- [*Note 1*: If the keyword `template` is used, the following unqualified
12
- name is considered to refer to a template [[temp.names]]. If a
13
- *simple-template-id* results and is followed by a `::`, the
14
- *id-expression* is a *qualified-id*. — *end note*]
 
 
 
 
15
 
16
- For the first option (dot) the first expression shall be a glvalue. For
17
- the second option (arrow) the first expression shall be a prvalue having
18
- pointer type. The expression `E1->E2` is converted to the equivalent
19
- form `(*(E1)).E2`; the remainder of [[expr.ref]] will address only the
20
- first option (dot).[^13]
21
 
22
- Abbreviating *postfix-expression*`.`*id-expression* as `E1.E2`, `E1` is
23
- called the *object expression*. If the object expression is of scalar
24
- type, `E2` shall name the pseudo-destructor of that same type (ignoring
 
 
 
 
 
25
  cv-qualifications) and `E1.E2` is a prvalue of type “function of ()
26
  returning `void`”.
27
 
28
  [*Note 2*: This value can only be used for a notional function call
29
  [[expr.prim.id.dtor]]. — *end note*]
@@ -36,68 +43,105 @@ definition of that class.
36
  when the class is complete [[class.member.lookup]]. — *end note*]
37
 
38
  [*Note 4*: [[basic.lookup.qual]] describes how names are looked up
39
  after the `.` and `->` operators. — *end note*]
40
 
41
- If `E2` is a bit-field, `E1.E2` is a bit-field. The type and value
42
- category of `E1.E2` are determined as follows. In the remainder of 
43
- [[expr.ref]], *cq* represents either `const` or the absence of `const`
44
- and *vq* represents either `volatile` or the absence of `volatile`. *cv*
45
- represents an arbitrary set of cv-qualifiers, as defined in 
46
- [[basic.type.qualifier]].
47
 
48
- If `E2` is declared to have type “reference to `T`”, then `E1.E2` is an
49
- lvalue of type `T`. If `E2` is a static data member, `E1.E2` designates
50
- the object or function to which the reference is bound, otherwise
51
- `E1.E2` designates the object or function to which the corresponding
52
- reference member of `E1` is bound. Otherwise, one of the following rules
53
- applies.
54
 
55
- - If `E2` is a static data member and the type of `E2` is `T`, then
56
- `E1.E2` is an lvalue; the expression designates the named member of
57
- the class. The type of `E1.E2` is `T`.
58
- - If `E2` is a non-static data member and the type of `E1` is “*cq1 vq1*
59
- `X`”, and the type of `E2` is “*cq2 vq2* `T`”, the expression
60
- designates the corresponding member subobject of the object designated
61
- by the first expression. If `E1` is an lvalue, then `E1.E2` is an
62
- lvalue; otherwise `E1.E2` is an xvalue. Let the notation *vq12* stand
63
- for the “union” of *vq1* and *vq2*; that is, if *vq1* or *vq2* is
64
- `volatile`, then *vq12* is `volatile`. Similarly, let the notation
65
- *cq12* stand for the “union” of *cq1* and *cq2*; that is, if *cq1* or
66
- *cq2* is `const`, then *cq12* is `const`. If `E2` is declared to be a
67
- `mutable` member, then the type of `E1.E2` is “*vq12* `T`”. If `E2` is
68
- not declared to be a `mutable` member, then the type of `E1.E2` is
69
- “*cq12* *vq12* `T`”.
70
- - If `E2` is an overload set, function overload resolution
71
- [[over.match]] is used to select the function to which `E2` refers.
72
- The type of `E1.E2` is the type of `E2` and `E1.E2` refers to the
73
- function referred to by `E2`.
 
 
 
 
 
 
 
 
 
74
  - If `E2` refers to a static member function, `E1.E2` is an lvalue.
75
  - Otherwise (when `E2` refers to a non-static member function),
76
- `E1.E2` is a prvalue. The expression can be used only as the
77
- left-hand operand of a member function call [[class.mfct]].
78
- \[*Note 5*: Any redundant set of parentheses surrounding the
79
- expression is ignored [[expr.prim.paren]]. *end note*]
80
- - If `E2` is a nested type, the expression `E1.E2` is ill-formed.
81
- - If `E2` is a member enumerator and the type of `E2` is `T`, the
82
- expression `E1.E2` is a prvalue of type `T` whose value is the value
83
- of the enumerator.
84
-
85
- If `E2` is a non-static member, the program is ill-formed if the class
86
- of which `E2` is directly a member is an ambiguous base
87
- [[class.member.lookup]] of the naming class [[class.access.base]] of
88
- `E2`.
89
-
90
- [*Note 6*: The program is also ill-formed if the naming class is an
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  ambiguous base of the class type of the object expression; see 
92
  [[class.access.base]]. — *end note*]
93
 
94
- If `E2` is a non-static member and the result of `E1` is an object whose
95
- type is not similar [[conv.qual]] to the type of `E1`, the behavior is
96
- undefined.
97
 
98
- [*Example 1*:
99
 
100
  ``` cpp
101
  struct A { int i; };
102
  struct B { int j; };
103
  struct D : A, B {};
 
1
  #### Class member access <a id="expr.ref">[[expr.ref]]</a>
2
 
3
  A postfix expression followed by a dot `.` or an arrow `->`, optionally
4
  followed by the keyword `template`, and then followed by an
5
+ *id-expression* or a *splice-expression*, is a postfix expression.
 
6
 
7
+ [*Note 1*: If the keyword `template` is used and followed by an
8
+ *id-expression*, the unqualified name is considered to refer to a
9
+ template [[temp.names]]. If a *simple-template-id* results and is
10
+ followed by a `::`, the *id-expression* is a
11
+ *qualified-id*. — *end note*]
12
 
13
+ For a dot that is followed by an expression that designates a static
14
+ member or an enumerator, the first expression is a discarded-value
15
+ expression [[expr.context]]; if the expression after the dot designates
16
+ a non-static data member, the first expression shall be a glvalue. A
17
+ postfix expression that is followed by an arrow shall be a prvalue
18
+ having pointer type. The expression `E1->E2` is converted to the
19
+ equivalent form `(*(E1)).E2`; the remainder of [[expr.ref]] will address
20
+ only the form using a dot.[^11]
21
 
22
+ The postfix expression before the dot is evaluated;[^12]
 
 
 
 
23
 
24
+ the result of that evaluation, together with the *id-expression* or
25
+ *splice-expression*, determines the result of the entire postfix
26
+ expression.
27
+
28
+ Abbreviating *postfix-expression*`.`*id-expression* or
29
+ *postfix-expression*`.`*splice-expression* as `E1.E2`, `E1` is called
30
+ the *object expression*. If the object expression is of scalar type,
31
+ `E2` shall name the pseudo-destructor of that same type (ignoring
32
  cv-qualifications) and `E1.E2` is a prvalue of type “function of ()
33
  returning `void`”.
34
 
35
  [*Note 2*: This value can only be used for a notional function call
36
  [[expr.prim.id.dtor]]. — *end note*]
 
43
  when the class is complete [[class.member.lookup]]. — *end note*]
44
 
45
  [*Note 4*: [[basic.lookup.qual]] describes how names are looked up
46
  after the `.` and `->` operators. — *end note*]
47
 
48
+ If `E2` is a *splice-expression*, then let `T1` be the type of `E1`.
49
+ `E2` shall designate either a member of `T1` or a direct base class
50
+ relationship (`T1`, `B`).
 
 
 
51
 
52
+ If `E2` designates a bit-field, `E1.E2` is a bit-field. The type and
53
+ value category of `E1.E2` are determined as follows. In the remainder
54
+ of  [[expr.ref]], *cq* represents either `const` or the absence of
55
+ `const` and *vq* represents either `volatile` or the absence of
56
+ `volatile`. *cv* represents an arbitrary set of cv-qualifiers, as
57
+ defined in  [[basic.type.qualifier]].
58
 
59
+ If `E2` designates an entity that is declared to have type “reference to
60
+ `T`”, then `E1.E2` is an lvalue of type `T`. In that case, if `E2`
61
+ designates a static data member, `E1.E2` designates the object or
62
+ function to which the reference is bound, otherwise `E1.E2` designates
63
+ the object or function to which the corresponding reference member of
64
+ `E1` is bound. Otherwise, one of the following rules applies.
65
+
66
+ - If `E2` designates a static data member and the type of `E2` is `T`,
67
+ then `E1.E2` is an lvalue; the expression designates the named member
68
+ of the class. The type of `E1.E2` is `T`.
69
+ - Otherwise, if `E2` designates a non-static data member and the type of
70
+ `E1` is *cq1 vq1* `X`”, and the type of `E2` is “*cq2 vq2* `T`”, the
71
+ expression designates the corresponding member subobject of the object
72
+ designated by `E1`. If `E1` is an lvalue, then `E1.E2` is an lvalue;
73
+ otherwise `E1.E2` is an xvalue. Let the notation *vq12* stand for the
74
+ “union” of *vq1* and *vq2*; that is, if *vq1* or *vq2* is `volatile`,
75
+ then *vq12* is `volatile`. Similarly, let the notation *cq12* stand
76
+ for the “union” of *cq1* and *cq2*; that is, if *cq1* or *cq2* is
77
+ `const`, then *cq12* is `const`. If the entity designated by `E2` is
78
+ declared to be a `mutable` member, then the type of `E1.E2` is “*vq12*
79
+ `T`”. If the entity designated by `E2` is not declared to be a
80
+ `mutable` member, then the type of `E1.E2` is “*cq12* *vq12* `T`”.
81
+ - Otherwise, if `E2` denotes an overload set, the expression shall be
82
+ the (possibly-parenthesized) left-hand operand of a member function
83
+ call [[expr.call]], and function overload resolution [[over.match]] is
84
+ used to select the function to which `E2` refers. The type of `E1.E2`
85
+ is the type of `E2` and `E1.E2` refers to the function referred to by
86
+ `E2`.
87
  - If `E2` refers to a static member function, `E1.E2` is an lvalue.
88
  - Otherwise (when `E2` refers to a non-static member function),
89
+ `E1.E2` is a prvalue. \[*Note 5*: Any redundant set of parentheses
90
+ surrounding the expression is ignored
91
+ [[expr.prim.paren]]. *end note*]
92
+ - Otherwise, if `E2` designates a nested type, the expression `E1.E2` is
93
+ ill-formed.
94
+ - Otherwise, if `E2` designates a member enumerator and the type of `E2`
95
+ is `T`, the expression `E1.E2` is a prvalue of type `T` whose value is
96
+ the value of the enumerator.
97
+ - Otherwise, if `E2` designates a direct base class relationship (D, B)
98
+ and the type of `E1` is cv `T`, the expression designates the direct
99
+ base class subobject of type B of the object designated by `E1`. If
100
+ `E1` is an lvalue, then `E1.E2` is an lvalue; otherwise, `E1.E2` is an
101
+ xvalue. The type of `E1.E2` is “cv `B`”.
102
+ \[*Note 6*: This can only occur in an expression of the form
103
+ `e1.[:e2:]`. *end note*]
104
+ \[*Example 1*:
105
+ ``` cpp
106
+ struct B {
107
+ int b;
108
+ };
109
+ struct C : B {
110
+ int get() const { return b; }
111
+ };
112
+ struct D : B, C { };
113
+
114
+ constexpr int f() {
115
+ D d = {1, {}};
116
+
117
+ // b unambiguously refers to the direct base class of type B,
118
+ // not the indirect base class of type B
119
+ B& b = d.[: std::meta::bases_of(^^D, std::meta::access_context::current())[0] :];
120
+ b.b += 10;
121
+ return 10 * b.b + d.get();
122
+ }
123
+ static_assert(f() == 110);
124
+ ```
125
+
126
+ — *end example*]
127
+ - Otherwise, the program is ill-formed.
128
+
129
+ If `E2` designates a non-static member (possibly after overload
130
+ resolution), the program is ill-formed if the class of which `E2`
131
+ designates a direct member is an ambiguous base [[class.member.lookup]]
132
+ of the designating class [[class.access.base]] of `E2`.
133
+
134
+ [*Note 7*: The program is also ill-formed if the naming class is an
135
  ambiguous base of the class type of the object expression; see 
136
  [[class.access.base]]. — *end note*]
137
 
138
+ If `E2` designates a non-static member (possibly after overload
139
+ resolution) and the result of `E1` is an object whose type is not
140
+ similar [[conv.qual]] to the type of `E1`, the behavior is undefined.
141
 
142
+ [*Example 2*:
143
 
144
  ``` cpp
145
  struct A { int i; };
146
  struct B { int j; };
147
  struct D : A, B {};