[temp.local] (original) (raw)
13 Templates [temp]
13.8 Name resolution [temp.res]
13.8.2 Locally declared names [temp.local]
Like normal (non-template) classes, class templates have an injected-class-name ([class.pre]).
When the injected-class-name of a class template specialization or partial specialization is used as a type-name, it is equivalent to the template-name followed by thetemplate-argument_s_of the class template specialization or partial specialization enclosed in<>.
[Example 1: template<template<class> class T> class A { };template<class T> class Y;template<> class Y<int> { Y* p; Y<char>* q; A<Y>* a; class B { template<class> friend class Y; };}; — _end example_]
The injected-class-name of a class template or class template specialization can be used as either a template-name or a type-namewherever it is named.
[Example 2: template <class T> struct Base { Base* p;};template <class T> struct Derived: public Base<T> { typename Derived::Base* p; };template<class T, template<class> class U = T::Base> struct Third { }; Third<Derived<int> > t; — _end example_]
A lookup that finds an injected-class-name ([class.member.lookup]) can result in an ambiguity in certain cases (for example, if it is found in more than one base class).
If all of the injected-class-names that are found refer to specializations of the same class template, and if the name is used as a template-name, the reference refers to the class template itself and not a specialization thereof, and is not ambiguous.
[Example 3: template <class T> struct Base { };template <class T> struct Derived: Base<int>, Base<char> { typename Derived::Base b; typename Derived::Base<double> d; }; — _end example_]
When the normal name of the template (i.e., the name from the enclosing scope, not the injected-class-name) is used, it always refers to the class template itself and not a specialization of the template.
[Example 4: template<class T> class X { X* p; X<T>* p2; X<int>* p3;::X* p4; }; — _end example_]
The name of a template parameter shall not be bound to any following declaration whose locus is contained by the scope to which the template parameter belongs.
[Example 5: template<class T, int i> class Y { int T; void f() { char T; } friend void T(); };template<class X> class X; — _end example_]
Unqualified name lookup considers the template parameter scope of a template-declarationimmediately after the outermost scope associated with the template declared (even if its parent scope does not contain the template-parameter-list).
[Note 1:
The scope of a class template, including its non-dependent base classes ([temp.dep.type], [class.member.lookup]), is searched before its template parameter scope.
— _end note_]
[Example 6: struct B { };namespace N { typedef void V;template<class T> struct A : B { typedef void C;void f();template<class U> void g(U);};} template<class V> void N::A<V>::f() { V v; } template<class B> template<class C> void N::A<B>::g(C) { B b; C c; } — _end example_]