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

6.9 KiB
Raw Blame History

[temp.local]

13 Templates [temp]

13.8 Name resolution [temp.res]

13.8.2 Locally declared names [temp.local]

1

#

Like normal (non-template) classes, class templates have an injected-class-name ([class.pre]).

The injected-class-name can be used as a template-name or a type-name.

When it is used with atemplate-argument-list, as a template-argument for a type template template parameter, or as the final identifier in the elaborated-type-specifier of a friend class template declaration, it is a template-name that refers to the class template itself.

Otherwise, it is a type-name equivalent to the template-name followed by the template argument list ([temp.decls.general], [temp.arg.general]) of the class template enclosed in <>.

2

#

When the injected-class-name of a class template specialization or partial specialization is used as a type-name, it is equivalent to the template-name followed by thetemplate-arguments of the class template specialization or partial specialization enclosed in<>.

[Example 1: template<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

#

The injected-class-name of a class template or class template specialization can be used as either a template-name or a type-name wherever it is named.

[Example 2: template struct Base { Base* p;};

template struct Derived: public Base {typename Derived::Base* p; // meaning Derived::Base};

template<class T, template class U = T::Base> struct Third { }; Third<Derived > t; // OK, default argument uses injected-class-name as a template — end example]

4

#

A lookup that finds an injected-class-name ([class.member.lookup]) can result in an ambiguity in certain cases (for example, if it is found in more than one base class).

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, the reference refers to the class template itself and not a specialization thereof, and is not ambiguous.

[Example 3: template struct Base { };template struct Derived: Base, Base {typename Derived::Base b; // error: ambiguoustypename Derived::Base d; // OK}; — end example]

5

#

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.

[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

#

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.

[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; // error: hidden by template parameter — end example]

7

#

Unqualified name lookup considers the template parameter scope of a template-declaration immediately after the outermost scope associated with the template declared (even if its parent scope does not contain the template-parameter-list).

[Note 1:

The scope of a class template, including its non-dependent base classes ([temp.dep.type], [class.member.lookup]), is searched before its template parameter scope.

— end note]

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