7 Expressions [expr]

7.5 Primary expressions [expr.prim]

7.5.5 Names [expr.prim.id]

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.
The component names of a nested-name-specifier are its identifier (if any) and those of its type-name, namespace-name, simple-template-id, and/or nested-name-specifier.
A splice-specifier or splice-specialization-specifier that is not followed by ​::​ is never interpreted as part of a splice-scope-specifier.
The keyword template may only be omitted from the form template splice-specialization-specifier ​::​ when the splice-specialization-specifier is preceded by typename.
[Example 1: template<int V> struct TCls { static constexpr int s = V; using type = int; }; int v1 = [:^^TCls<1>:]::s; int v2 = template [:^^TCls:]<2>::s; // OK, template binds to splice-scope-specifier typename [:^^TCls:]<3>::type v3 = 3; // OK, typename binds to the qualified name template [:^^TCls:]<3>::type v4 = 4; // OK, template binds to the splice-scope-specifier typename template [:^^TCls:]<3>::type v5 = 5; // OK, same as v3 [:^^TCls:]<3>::type v6 = 6; // error: unexpected < — end example]
A declaration that uses a declarative nested-name-specifier shall be a friend declaration or inhabit a scope that contains the entity being redeclared or specialized.
The entity designated by a nested-name-specifier is determined as follows:
A qualified-id shall not be of the form nested-name-specifier template ~ computed-type-specifier nor of the form computed-type-specifier ​::​ ~ type-name.
The result of a qualified-id Q is the entity it denotes ([basic.lookup.qual]).
If Q appears in the predicate of a contract assertion C ([basic.contract]) and the entity is
  • a variable declared outside of C of object type T,
  • a variable declared outside of C of type “reference to T”, or
  • a structured binding of type T whose corresponding variable is declared outside of C,
then the type of the expression is const T.
Otherwise, the type of the expression is the type of the result.
The result is an lvalue if the member is
  • a function other than a non-static member function,
  • a non-static member function if Q is the operand of a unary & operator,
  • a variable,
  • a structured binding ([dcl.struct.bind]), or
  • a data member,
and a prvalue otherwise.