- 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*
|
| 6 |
-
the dot or arrow is evaluated;[^12]
|
| 7 |
|
| 8 |
-
the
|
| 9 |
-
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
-
|
| 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 |
-
|
| 23 |
-
|
| 24 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| 42 |
-
|
| 43 |
-
|
| 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`
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
`
|
| 52 |
-
|
| 53 |
-
|
| 54 |
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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.
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
-
|
| 82 |
-
expression `E1.E2` is a prvalue of type `T` whose value is
|
| 83 |
-
of the enumerator.
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
`E2`.
|
| 89 |
-
|
| 90 |
-
[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
ambiguous base of the class type of the object expression; see
|
| 92 |
[[class.access.base]]. — *end note*]
|
| 93 |
|
| 94 |
-
If `E2`
|
| 95 |
-
|
| 96 |
-
undefined.
|
| 97 |
|
| 98 |
-
[*Example
|
| 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 {};
|