[temp.dep.type]
13 Templates [temp]
13.8 Name resolution [temp.res]
13.8.3 Dependent names [temp.dep]
13.8.3.2 Dependent types [temp.dep.type]
A name or template-id refers to the current instantiation if it is
- in the definition of a class template, a nested class of a class template, a member of a class template, or a member of a nested class of a class template, the injected-class-name of the class template or nested class,
- in the definition of a primary class template or a member of a primary class template, the name of the class template followed by the template argument list of its template-head ([temp.arg]) enclosed in <> (or an equivalent template alias specialization),
- in the definition of a nested class of a class template, the name of the nested class referenced as a member of the current instantiation,
- in the definition of a class template partial specialization or a member of a class template partial specialization, the name of the class template followed by a template argument list equivalent to that of the partial specialization ([temp.spec.partial]) enclosed in <> (or an equivalent template alias specialization), or
- in the definition of a templated function, the name of a local class ([class.local]).
A template argument that is equivalent to a template parameter can be used in place of that template parameter in a reference to the current instantiation.
A template argument is equivalent to a type template parameter if it denotes the same type.
A template argument is equivalent to a constant template parameter if it is an identifier that names a variable that is equivalent to the template parameter.
A variable is equivalent to a template parameter if
- it has the same type as the template parameter (ignoring cv-qualification) and
- its initializer consists of a single identifier that names the template parameter or, recursively, such a variable.
[Example 1: template <class T> class A { A* p1; A<T>* p2; A<T*> p3; ::A<T>* p4; class B { B* p1; A<T>::B* p2; typename A<T*>::B* p3; }; }; template <class T> class A<T*> { A<T*>* p1; A<T>* p2; }; template <class T1, class T2, int I> struct B { B<T1, T2, I>* b1; B<T2, T1, I>* b2; typedef T1 my_T1; static const int my_I = I; static const int my_I2 = I+0; static const int my_I3 = my_I; static const long my_I4 = I; static const int my_I5 = (I); B<my_T1, T2, my_I>* b3; B<my_T1, T2, my_I2>* b4; B<my_T1, T2, my_I3>* b5; B<my_T1, T2, my_I4>* b6; B<my_T1, T2, my_I5>* b7; }; — end example]
A dependent base class is a base class that is a dependent type and is not the current instantiation.
A qualified ([basic.lookup.qual]) or unqualified name is a member of the current instantiation if
- its lookup context, if it is a qualified name, is the current instantiation, and
- lookup for it finds any member of a class that is the current instantiation
[Example 3: template <class T> class A { static const int i = 5; int n1[i]; int n2[A::i]; int n3[A<T>::i]; int f(); }; template <class T> int A<T>::f() { return i; } — end example]
A qualified or unqualified name names a dependent member of the current instantiation if it is a member of the current instantiation that, when looked up, refers to at least one member declaration (including a using-declarator whose terminal name is dependent) of a class that is the current instantiation.
A qualified name ([basic.lookup.qual]) is dependent if
- it is a conversion-function-id whose conversion-type-id is dependent, or
- its lookup context is dependent and is not the current instantiation, or
- its lookup context is the current instantiation and it is operator=,112 or
- its lookup context is the current instantiation and has at least one dependent base class, and qualified name lookup for the name finds nothing ([basic.lookup.qual]).
[Example 4: struct A { using B = int; A f(); }; struct C : A {}; template<class T> void g(T t) { decltype(t.A::f())::B i; } template void g(C); — end example]
If, for a given set of template arguments, a specialization of a template is instantiated that refers to a member of the current instantiation with a qualified name, the name is looked up in the template instantiation context.
If the result of this lookup differs from the result of name lookup in the template definition context, name lookup is ambiguous.
[Example 5: struct A { int m; }; struct B { int m; }; template<typename T> struct C : A, T { int f() { return this->m; } int g() { return m; } }; template int C<B>::f(); template int C<B>::g(); — end example]
An initializer is dependent if any constituent expression ([intro.execution]) of the initializer is type-dependent.
A placeholder type ([dcl.spec.auto.general]) is dependent if it designates a type deduced from a dependent initializer.
[Example 6: template<class T, class V> struct S { S(T); }; template<class U> struct A { template<class T> using X = S<T, U>; template<class T> using Y = S<T, int>; void f() { new X(1); new Y(1); } }; — end example]
A type is dependent if it is
- a template parameter,
- denoted by a dependent (qualified) name,
- a nested class or enumeration that is a direct member of a class that is the current instantiation,
- a cv-qualified type where the cv-unqualified type is dependent,
- a compound type constructed from any dependent type,
- an array type whose element type is dependent or whose bound (if any) is value-dependent,
- a function type whose parameters include one or more function parameter packs,
- a function type whose exception specification is value-dependent,
- denoted by a dependent placeholder type,
- denoted by a dependent placeholder for a deduced class type,
- denoted by a simple-template-id in which either the template name is a template parameter or any of the template arguments is dependent ([temp.dep.temp]),113
- a pack-index-specifier,
- denoted by decltype(expression), where expression is type-dependent, or
- denoted by a splice-type-specifier in which either the splice-specifier or splice-specialization-specifier is dependent ([temp.dep.splice]).