7 Expressions [expr]

7.6 Compound expressions [expr.compound]

7.6.1 Postfix expressions [expr.post]

7.6.1.4 Class member access [expr.ref]

A postfix expression followed by a dot . or an arrow ->, optionally followed by the keyword template ([temp.names]), and then followed by an id-expression, is a postfix expression.
The postfix expression before the dot or arrow is evaluated;59 the result of that evaluation, together with the id-expression, determines the result of the entire postfix expression.
For the first option (dot) the first expression shall be a glvalue.
For the second option (arrow) the first expression 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 first option (dot).60
Abbreviating postfix-expression.id-expression as E1.E2, E1 is called the object 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 an lvalue of type “function of () returning void.
Note
:
This value can only be used for a notional function call ([expr.prim.id.dtor]).
— end note
 ]
Otherwise, the object expression shall be of class type.
The class type shall be complete unless the class member access appears in the definition of that class.
Note
:
If the class is incomplete, lookup in the complete class type is required to refer to the same declaration ([basic.scope.class]).
— end note
 ]
The id-expression shall name a member of the class or of one of its base classes.
Note
:
Because the name of a class is inserted in its class scope ([class]), the name of a class is also considered a nested member of that class.
— end note
 ]
Note
:
[basic.lookup.classref] describes how names are looked up after the . and -> operators.
— end note
 ]
If E2 is a bit-field, E1.E2 is a bit-field.
The type and value category of E1.E2 are determined as follows.
In the remainder of [expr.ref], cq represents either const or the absence of const and vq represents either volatile or the absence of volatile.
cv represents an arbitrary set of cv-qualifiers, as defined in [basic.type.qualifier].
If E2 is declared to have type “reference to T”, then E1.E2 is an lvalue; the type of E1.E2 is T.
Otherwise, one of the following rules applies.
If E2 is a non-static data member or a non-static member function, the program is ill-formed if the class of which E2 is directly a member is an ambiguous base ([class.member.lookup]) of the naming class ([class.access.base]) of E2.
Note
:
The program is also ill-formed if the naming class is an ambiguous base of the class type of the object expression; see [class.access.base].
— end note
 ]
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.
Note that (*(E1)) is an lvalue.