7 Expressions [expr]

7.5 Primary expressions [expr.prim]

7.5.4 Names [expr.prim.id]

7.5.4.1 General [expr.prim.id.general]

An id-expression is a restricted form of a primary-expression.
[Note 1: — end note]
If an id-expression E denotes a member M of an anonymous union ([class.union.anon]) U:
  • If U is a non-static data member, E refers to M as a member of the lookup context of the terminal name of E (after any transformation to a class member access expression ([class.mfct.non-static])).
    [Example 1:
    o.x is interpreted as o.u.x, where u names the anonymous union member.
    — end example]
  • Otherwise, E is interpreted as a class member access ([expr.ref]) that designates the member subobject M of the anonymous union variable for U.
    [Note 2:
    Under this interpretation, E no longer denotes a non-static data member.
    — end note]
    [Example 2:
    N​::​x is interpreted as N​::​u.x, where u names the anonymous union variable.
    — end example]
An id-expression that denotes a non-static data member or non-static member function of a class can only be used:
  • as part of a class member access in which the object expression refers to the member's class53 or a class derived from that class, or
  • to form a pointer to member ([expr.unary.op]), or
  • if that id-expression denotes a non-static data member and it appears in an unevaluated operand.
    [Example 3: struct S { int m; }; int i = sizeof(S::m); // OK int j = sizeof(S::m + 42); // OK — end example]
A potentially-evaluated id-expression that denotes an immediate function shall appear only
For an id-expression that denotes an overload set, overload resolution is performed to select a unique function ([over.match], [over.over]).
[Note 3:
A program cannot refer to a function with a trailing requires-clause whose constraint-expression is not satisfied, because such functions are never selected by overload resolution.
[Example 4: template<typename T> struct A { static void f(int) requires false; } void g() { A<int>::f(0); // error: cannot call f void (*p1)(int) = A<int>::f; // error: cannot take the address of f decltype(A<int>::f)* p2 = nullptr; // error: the type decltype(A<int>​::​f) is invalid }
In each case, the constraints of f are not satisfied.
In the declaration of p2, those constraints are required to be satisfied even though f is an unevaluated operand.
— end example]
— end note]
53)53)
This also applies when the object expression is an implicit (*this) ([class.mfct.non-static]).