[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

]