A postfix expression followed by a dot . or an arrow ->,
optionally followed by the keyword
template, and then followed by an
id-expression or a splice-expression,
is a postfix expression.
For a dot that is followed by an expression
that designates a static member or an enumerator,
the first expression is a discarded-value expression ([expr.context]);
if the expression after the dot designates a non-static data member,
the first expression shall be a glvalue.
A postfix expression that is followed by an arrow
shall be a prvalue having pointer type.
The expression E1->E2 is
converted to the equivalent form (*(E1)).E2; the remainder of
[expr.ref] will address only the form using a dot.49
The postfix expression before the dot is evaluated;50
the result of that evaluation,
together with
the id-expression or splice-expression,
determines the result of the entire postfix expression.
If the object expression is of scalar type,
E2 shall name the pseudo-destructor
of that same type (ignoring cv-qualifications) and
E1.E2 is a prvalue of type “function of () returning void”.
If E2 designates an entity
that is declared to have type “reference to T”, then
E1.E2 is an lvalue of type T.
In that case, if E2 designates a static data member,
E1.E2 designates the object or function to which
the reference is bound,
otherwise E1.E2 designates the object or function to which
the corresponding reference member of E1 is bound.
Otherwise, if E2 designates a non-static data member and the type of
E1 is “cq1 vq1X”, and the type of E2
is “cq2 vq2T”, the expression designates the corresponding
member subobject of the object designated by E1.
If E1
is an lvalue, then E1.E2 is an lvalue;
otherwise E1.E2 is an xvalue.
Let the notation vq12 stand for the “union” of
vq1 and vq2; that is, if vq1 or vq2
is volatile, then vq12 is volatile.
Similarly,
let the notation cq12 stand for the “union” of cq1
and cq2; that is, if cq1 or cq2 is
const, then cq12 is const.
If the entity designated by E2
is declared to be a mutable member,
then the type of E1.E2 is “vq12T”.
If the entity designated by E2
is not declared to be a mutable member,
then the type of E1.E2 is “cq12vq12T”.
If E2 denotes an overload set,
the expression shall be the (possibly-parenthesized) left-hand operand of
a member function call ([expr.call]), and
function overload resolution ([over.match])
is used to select the function to which E2 refers.
The type of E1.E2 is the type of E2
and E1.E2 refers to the function referred to by E2.
If E2 designates a direct base class relationship (D,B)
and the type of E1 is cvT,
the expression designates the direct base class subobject of type B
of the object designated by E1.
If E1 is an lvalue,
then E1.E2 is an lvalue;
otherwise, E1.E2 is an xvalue.
This can only occur in an expression of the form e1.[:e2:].
— end note]
[Example 1: struct B {int b;
};
struct C : B {int get()const{return b; }};
struct D : B, C {};
constexprint f(){
D d ={1, {}};
// b unambiguously refers to the direct base class of type B,// not the indirect base class of type B
B& b = d.[: std::meta::bases_of(^^D, std::meta::access_context::current())[0]:];
b.b +=10;
return10* b.b + d.get();
}static_assert(f()==110);
— end example]
If E2 designates a non-static member
(possibly after overload resolution),
the program is ill-formed if the class of which E2 designates
a direct member is an ambiguous base ([class.member.lookup]) of
the designating class ([class.access.base]) of E2.
If E2 designates a non-static member
(possibly after overload resolution) and
the result of E1 is an object whose type
is not similar ([conv.qual]) to the type of E1,
the behavior is undefined.
[Example 2: struct A {int i; };
struct B {int j; };
struct D : A, B {};
void f(){
D d;
static_cast<B&>(d).j; // OK, object expression designates the B subobject of dreinterpret_cast<B&>(d).j; // undefined behavior} — end example]
If the class member
access expression is evaluated, the subexpression evaluation happens even if the
result is unnecessary to determine
the value of the entire postfix expression, for example if the
id-expression denotes a static member.