13 Templates [temp]

13.8 Name resolution [temp.res]

13.8.3 Dependent names [temp.dep]

13.8.3.1 General [temp.dep.general]

Inside a template, some constructs have semantics which may differ from one instantiation to another.
Such a construct depends on the template parameters.
In particular, types and expressions may depend on the type and/or value of template parameters (as determined by the template arguments) and this determines the context for name lookup for certain names.
An expression may be type-dependent (that is, its type may depend on a template parameter) or value-dependent (that is, its value when evaluated as a constant expression ([expr.const]) may depend on a template parameter) as described below.
In an expression of the form: where the postfix-expression is an unqualified-id, the unqualified-id denotes a dependent name if
If an operand of an operator is a type-dependent expression, the operator also denotes a dependent name.
[Note 1:
Such names are unbound and are looked up at the point of the template instantiation ([temp.point]) in both the context of the template definition and the context of the point of instantiation ([temp.dep.candidate]).
— end note]
[Example 1: template<class T> struct X : B<T> { typename T::A* pa; void f(B<T>* pb) { static int i = B<T>::i; pb->j++; } };
The base class name B<T>, the type name T​::​A, the names B<T>​::​i and pb->j explicitly depend on the template-parameter.
— end example]
In the definition of a class or class template, the scope of a dependent base class is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.
[Example 2: typedef double A; template<class T> class B { typedef int A; }; template<class T> struct X : B<T> { A a; // a has type double };
The type name A in the definition of X<T> binds to the typedef name defined in the global namespace scope, not to the typedef name defined in the base class B<T>.
— end example]
[Example 3: struct A { struct B { /* ... */ }; int a; int Y; }; int a; template<class T> struct Y : T { struct B { /* ... */ }; B b; // The B defined in Y void f(int i) { a = i; } // ​::​a Y* p; // Y<T> }; Y<A> ya;
The members A​::​B, A​::​a, and A​::​Y of the template argument A do not affect the binding of names in Y<A>.
— end example]