[temp.local] # 13 Templates [[temp]](./#temp) ## 13.8 Name resolution [[temp.res]](temp.res#temp.local) ### 13.8.2 Locally declared names [temp.local] [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5110) Like normal (non-template) classes, class templates have an injected-class-name ([[class.pre]](class.pre "11.1 Preamble"))[.](#1.sentence-1) The injected-class-name can be used as a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") or a [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]")[.](#1.sentence-2) When it is used with a[*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]"), as a [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") for a type template template parameter, or as the final identifier in the [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]") of a friend class template declaration, it is a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") that refers to the class template itself[.](#1.sentence-3) Otherwise, it is a [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") equivalent to the [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") followed by the template argument list ([[temp.decls.general]](temp.decls.general "13.7.1 General"), [[temp.arg.general]](temp.arg.general "13.4.1 General")) of the class template enclosed in <>[.](#1.sentence-4) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5130) When the injected-class-name of a class template specialization or partial specialization is used as a [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]"), it is equivalent to the [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") followed by the[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* of the class template specialization or partial specialization enclosed in<>[.](#2.sentence-1) [*Example [1](#example-1)*: template class T> class A { };template class Y;template<> class Y { Y* p; // meaning Y Y* q; // meaning Y A* a; // meaning A<​::​Y>class B {template friend class Y; // meaning ​::​Y};}; — *end example*] [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5153) The injected-class-name of a class template or class template specialization can be used as either a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") or a [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") wherever it is named[.](#3.sentence-1) [*Example [2](#example-2)*: template struct Base { Base* p;}; template struct Derived: public Base {typename Derived::Base* p; // meaning Derived​::​Base}; template class U = T::Base> struct Third { }; Third > t; // OK, default argument uses injected-class-name as a template — *end example*] [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5173) A lookup that finds an injected-class-name ([[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup")) can result in an ambiguity in certain cases (for example, if it is found in more than one base class)[.](#4.sentence-1) 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*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]"), the reference refers to the class template itself and not a specialization thereof, and is not ambiguous[.](#4.sentence-2) [*Example [3](#example-3)*: template struct Base { };template struct Derived: Base, Base {typename Derived::Base b; // error: ambiguoustypename Derived::Base d; // OK}; — *end example*] [5](#5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5193) 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[.](#5.sentence-1) [*Example [4](#example-4)*: template class X { X* p; // meaning X X* p2; X* p3; ::X* p4; // error: missing template argument list// ​::​X does not refer to the injected-class-name}; — *end example*] [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5211) 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[.](#6.sentence-1) [*Example [5](#example-5)*: template class Y {int T; // error: template parameter hiddenvoid f() {char T; // error: template parameter hidden}friend void T(); // OK, no name bound}; template class X; // error: hidden by template parameter — *end example*] [7](#7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5230) Unqualified name lookup considers the template parameter scope of a [*template-declaration*](temp.pre#nt:template-declaration "13.1 Preamble [temp.pre]") immediately after the outermost scope associated with the template declared (even if its parent scope does not contain the [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]"))[.](#7.sentence-1) [*Note [1](#note-1)*: The scope of a class template, including its non-dependent base classes ([[temp.dep.type]](temp.dep.type "13.8.3.2 Dependent types"), [[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup")), is searched before its template parameter scope[.](#7.sentence-2) — *end note*] [*Example [6](#example-6)*: struct B { };namespace N {typedef void V; template struct A : B {typedef void C; void f(); template void g(U); };}template void N::A::f() { // N​::​V not considered here V v; // V is still the template parameter, not N​::​V}template template void N::A::g(C) { B b; // B is the base class, not the template parameter C c; // C is the template parameter, not A's C} — *end example*]