This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

118
cppdraft/temp/local.md Normal file
View 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.1Preamble"))[.](#1.sentence-1)
The
injected-class-name can be used
as a [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") or a [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple type specifiers[dcl.type.simple]")[.](#1.sentence-2)
When it is used with a[*template-argument-list*](temp.names#nt:template-argument-list "13.3Names of template specializations[temp.names]"),
as a [*template-argument*](temp.names#nt:template-argument "13.3Names 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.5Elaborated type specifiers[dcl.type.elab]") of
a friend class template declaration,
it is a [*template-name*](temp.names#nt:template-name "13.3Names 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.3Simple type specifiers[dcl.type.simple]") equivalent to the [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") followed by
the template argument list ([[temp.decls.general]](temp.decls.general "13.7.1General"), [[temp.arg.general]](temp.arg.general "13.4.1General"))
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.3Simple type specifiers[dcl.type.simple]"),
it is equivalent to the [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") followed by the[*template-argument*](temp.names#nt:template-argument "13.3Names 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.3Names of template specializations[temp.names]") or a [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3Simple 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.2Member 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.3Names 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.1Preamble[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.1Preamble[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.2Dependent types"), [[class.member.lookup]](class.member.lookup "6.5.2Member 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*]