[expr.prim.id.qual]
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]
[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; typename [:^^TCls:]<3>::type v3 = 3; template [:^^TCls:]<3>::type v4 = 4; typename template [:^^TCls:]<3>::type v5 = 5; [:^^TCls:]<3>::type v6 = 6; — 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:
The nested-name-specifier :: designates the global namespace.
Letting S be the specialization of T corresponding to the template argument list of the splice-specialization-specifier, S shall either be a class template specialization or an alias template specialization that denotes a class or enumeration type.
The nested-name-specifier designates the underlying entity of S.
If a nested-name-specifier N is declarative and has a simple-template-id with a template argument list A that involves a template parameter, let T be the template nominated by N without A.
T shall be a class template.
Otherwise, N designates the partial specialization ([temp.spec.partial]) of T whose template argument list is equivalent to A ([temp.over.link]); the program is ill-formed if no such partial specialization exists.
If the nested-name-specifier is not declarative, the entity shall not be a template.
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.