Search code examples
c++c++11scopeoperatorsmember

What does the scope resolution operator return in case of Type::var?


Consider the following example:

class A { int x; };

Now what is A::x?

  • It cannot be an lvalue because it does not refer to a storage Location.
  • It cannot be a type, because the type would be decltype(A::x).

Solution

  • It is, in fact, an lvalue. [expr.prim.id.qual]/2:

    A nested-name-specifier that denotes a class [...] followed by the name of a member of either that class ([class.mem]) or one of its base classes, is a qualified-id [...]. The result is the member. The type of the result is the type of the member. The result is an lvalue if the member is a static member function or a data member and a prvalue otherwise.

    Though its usage outside a class member access expression is severely restricted by [expr.prim.id]/2, it can notably be used in unevaluated operands, where its lvalueness can manifest:

    struct A {
        int x;
    };
    
    void f(int &);
    
    using p = decltype(&(A::x)); // p is int*; the parens prevents forming a pointer-to-member
    using q = decltype(f(A::x)); // q is void