[expr.prim.id] (original) (raw)

7 Expressions [expr]

7.5 Primary expressions [expr.prim]

7.5.5 Names [expr.prim.id]

7.5.5.1 General [expr.prim.id.general]

If an id-expression E denotes a non-static non-type member of some class C at a point where the current class ([expr.prim.this]) is X and

the id-expression is transformed into a class member access expression using (*this) as the object expression.

[Note 2:

If C is not X or a base class of X, the class member access expression is ill-formed.

Also, if the id-expression occurs within a static or explicit object member function, the class member access is ill-formed.

— _end note_]

This transformation does not apply in the template definition context ([temp.dep.type]).

If an id-expression E denotes a member M of an anonymous union ([class.union.anon]) U:

An id-expression that denotes a non-static data member or implicit object member function of a class can only be used:

For an id-expression that denotes an overload set, overload resolution is performed to select a unique function ([over.match], [over.over]).

[Note 4:

A program cannot refer to a function with a trailing requires-clausewhose 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); void (*p1)(int) = A<int>::f; decltype(A<int>::f)* p2 = nullptr; }

In each case, the constraints of f are not satisfied.

In the declaration of p2, those constraints need to be satisfied even thoughf is an unevaluated operand.

— _end example_]

— _end note_]

7.5.5.2 Unqualified names [expr.prim.id.unqual]

The terminal name of a construct is the component name of that construct that appears lexically last.

If naming the entity from outside of an unevaluated operand within Swould refer to an entity captured by copy in some intervening lambda-expression, then let E be the innermost such lambda-expression.

If the entity is a template parameter object for a template parameter of type T ([temp.param]), the type of the expression is const T.

In all other cases, the type of the expression is the type of the entity.

[Note 4:

The type will be adjusted as described in [expr.type]if it is cv-qualified or is a reference type.

— _end note_]

The expression is an xvalue if it is move-eligible (see below); an lvalue if the entity is a function, variable, structured binding, data member, or template parameter object; and a prvalue otherwise ([basic.lval]); it is a bit-field if the identifier designates a bit-field.

[Example 1: void f() { float x, &r = x;[=]() -> decltype((x)) { decltype(x) y1; decltype((x)) y2 = y1; decltype(r) r1 = y1; decltype((r)) r2 = y2; return y2;};[=](decltype((x)) y) { decltype((x)) z = x; };[=] { [](decltype((x)) y) {}; [x=1](decltype((x)) y) { decltype((x)) z = x; };};} — _end example_]

7.5.5.3 Qualified names [expr.prim.id.qual]

The component names of a qualified-id are those of its nested-name-specifier and unqualified-id.

A declaration that uses a declarative nested-name-specifiershall be a friend declaration or inhabit a scope that contains the entity being redeclared or specialized.

The nested-name-specifier ​::​ nominates the global namespace.

If a nested-name-specifier Nis declarative and has a simple-template-id with a template argument list Athat involves a template parameter, let T be the template nominated by N without A.

T shall be a class template.

If the nested-name-specifier is not declarative, the entity shall not be a template.

The type of the expression is the type of the result.

The result is an lvalue if the member is

and a prvalue otherwise.

7.5.5.5 Destruction [expr.prim.id.dtor]

An id-expression that denotes the destructor of a type Tnames the destructor of Tif T is a class type ([class.dtor]), otherwise the id-expression is said to name a pseudo-destructor.

[Example 1: struct C { };void f() { C * pc = new C;using C2 = C; pc->C::~C2(); C().C::~C(); using T = int;0 .T::~T(); 0.T::~T(); } — _end example_]