[temp.local] (original) (raw)
13 Templates [temp]
13.8 Name resolution [temp.res]
13.8.1 Locally declared names [temp.local]
Like normal (non-template) classes, class templates have an injected-class-name ([class.pre]).
Within the scope of a class template specialization or partial specialization, when the injected-class-name is used as a type-name, it is equivalent to the template-name followed by thetemplate-argumentsof the class template specialization or partial specialization enclosed in<>.
[ Example
:
template<template class T> class A { };
template class Y;
template<> class Y {
Y* p;
Y* q;
A* a;
class B {
template 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 in scope.
[ Example
:
template struct Base { Base* p; };
template struct Derived: public Base {
typename Derived::Base* p;
};
template<class T, template class U = T::template Base> struct Third { }; Third<Derived > 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
:
template struct Base { };
template struct Derived: Base, Base {
typename Derived::Base b;
typename Derived::Base 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
:
template class X {
X* p;
X* p2;
X* p3;
::X* p4;
};
— end example
]
The name of atemplate-parametershall not be redeclared within its scope (including nested scopes).
[ Example
:
template<class T, int i> class Y {
int T;
void f() {
char T;
}
};
template class X;
— end example
]
In the definition of a member of a class template that appears outside of the class template definition, the name of a member of the class template hides the name of atemplate-parameterof any enclosing class templates (but not a template-parameter of the member if the member is a class or function template).
[ Example
:
template struct A { struct B { }; typedef void C; void f(); template void g(U); };
template void A::f() {
B b;
}
template template void A::g(C) {
B b;
C c;
}
— end example
]
In the definition of a member of a class template that appears outside of the namespace containing the class template definition, the name of atemplate-parameterhides the name of a member of this namespace.
[ Example
:
namespace N {
class C { };
template class B {
void f(T);
};
}
template void N::B::f(C) {
C b;
}
— end example
]
In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, for each non-dependent base class ([temp.dep.type]), if the name of the base class or the name of a member of the base class is the same as the name of atemplate-parameter, the base class name or member name hides thetemplate-parametername.
[ Example
:
struct A { struct B { }; int a; int Y; };
template<class B, class a> struct X : A {
B b;
a b;
};
— end example
]