119 lines
6.9 KiB
Markdown
119 lines
6.9 KiB
Markdown
[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<template<class> class T> class A { };template<class T> class Y;template<> class Y<int> { Y* p; // meaning Y<int> Y<char>* q; // meaning Y<char> A<Y>* a; // meaning A<::Y>class B {template<class> 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 <class T> struct Base { Base* p;};
|
||
|
||
template <class T> struct Derived: public Base<T> {typename Derived::Base* p; // meaning Derived::Base<T>};
|
||
|
||
template<class T, template<class> class U = T::Base> struct Third { };
|
||
Third<Derived<int> > 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 <class T> struct Base { };template <class T> struct Derived: Base<int>, Base<char> {typename Derived::Base b; // error: ambiguoustypename Derived::Base<double> 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 T> class X { X* p; // meaning X<T> X<T>* p2;
|
||
X<int>* 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 T, int i> 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> 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<class T> struct A : B {typedef void C; void f(); template<class U> void g(U); };}template<class V> void N::A<V>::f() { // N::V not considered here V v; // V is still the template parameter, not N::V}template<class B> template<class C> void N::A<B>::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*]
|