Files
cppdraft_translate/cppdraft/temp/local.md
2025-10-25 03:02:53 +03:00

119 lines
6.9 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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*]