Init
This commit is contained in:
118
cppdraft/temp/local.md
Normal file
118
cppdraft/temp/local.md
Normal file
@@ -0,0 +1,118 @@
|
||||
[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*]
|
||||
Reference in New Issue
Block a user