[temp.dep.type]

# 13 Templates [[temp]](./#temp)

## 13.8 Name resolution [[temp.res]](temp.res#temp.dep.type)

### 13.8.3 Dependent names [[temp.dep]](temp.dep#type)

#### 13.8.3.2 Dependent types [temp.dep.type]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5358)

A name or [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") refers to the[*current instantiation*](#def:current_instantiation "13.8.3.2 Dependent types [temp.dep.type]") if it is

- [(1.1)](#1.1)

in the definition of a class template, a nested class of a class template,
a member of a class template, or a member of a nested class of a class template,
the [injected-class-name](class.pre#def:injected-class-name "11.1 Preamble [class.pre]") of the class template or nested class,

- [(1.2)](#1.2)

in the definition of a primary class template
or a member of a primary class template, the name of the
class template followed by the template argument list of
its [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") ([[temp.arg]](temp.arg "13.4 Template arguments")) enclosed in<> (or an equivalent template alias specialization),

- [(1.3)](#1.3)

in the definition of a nested class of a class template,
the name of the nested class referenced as a member of the
current instantiation,

- [(1.4)](#1.4)

in the definition of a class template partial specialization
or a member of a class template partial specialization, the name of
the class template followed by a template argument list
equivalent to that of the partial specialization ([[temp.spec.partial]](temp.spec.partial "13.7.6 Partial specialization"))
enclosed in <> (or an equivalent template alias specialization), or

- [(1.5)](#1.5)

in the definition of a templated function,
the name of a local class ([[class.local]](class.local "11.6 Local class declarations"))[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5388)

A template argument that is equivalent to a template
parameter can be used in place of that
template parameter in a reference to the current instantiation[.](#2.sentence-1)

A template argument is equivalent to a type template parameter
if it denotes the same type[.](#2.sentence-2)

A template argument is equivalent to a constant template parameter
if it is an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") that names a variable
that is equivalent to the template parameter[.](#2.sentence-3)

A variable is equivalent to a template parameter if

- [(2.1)](#2.1)

it has the same type as the template parameter
 (ignoring cv-qualification) and

- [(2.2)](#2.2)

its initializer consists of a single [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") that names the template parameter or, recursively, such a variable[.](#2.sentence-4)

[*Note [1](#note-1)*:

Using a parenthesized variable name breaks the equivalence[.](#2.sentence-5)

â *end note*]

[*Example [1](#example-1)*: template <class T> class A { A* p1; // A is the current instantiation A<T>* p2; // A<T> is the current instantiation A<T*> p3; // A<T*> is not the current instantiation::A<T>* p4; // ​::​A<T> is the current instantiationclass B { B* p1; // B is the current instantiation A<T>::B* p2; // A<T>​::​B is the current instantiationtypename A<T*>::B* p3; // A<T*>​::​B is not the current instantiation};};

template <class T> class A<T*> { A<T*>* p1; // A<T*> is the current instantiation A<T>* p2; // A<T> is not the current instantiation};

template <class T1, class T2, int I> struct B { B<T1, T2, I>* b1; // refers to the current instantiation B<T2, T1, I>* b2; // not the current instantiationtypedef T1 my_T1; static const int my_I = I; static const int my_I2 = I+0; static const int my_I3 = my_I; static const long my_I4 = I; static const int my_I5 = (I);
 B<my_T1, T2, my_I>* b3; // refers to the current instantiation B<my_T1, T2, my_I2>* b4; // not the current instantiation B<my_T1, T2, my_I3>* b5; // refers to the current instantiation B<my_T1, T2, my_I4>* b6; // not the current instantiation B<my_T1, T2, my_I5>* b7; // not the current instantiation}; â *end example*]

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5446)

A [*dependent base class*](#def:base_class,dependent "13.8.3.2 Dependent types [temp.dep.type]") is a base class that is a dependent type and is
not the current instantiation[.](#3.sentence-1)

[*Note [2](#note-2)*:

A base class can be the current instantiation in the case of a nested class
naming an enclosing class as a base[.](#3.sentence-2)

[*Example [2](#example-2)*: template<class T> struct A {typedef int M; struct B {typedef void M; struct C; };};

template<class T> struct A<T>::B::C : A<T> { M m; // OK, A<T>​::​M}; â *end example*]

â *end note*]

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5470)

A qualified ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup")) or unqualified name is a[*member of the current instantiation*](#def:current_instantiation,member_of_the "13.8.3.2 Dependent types [temp.dep.type]") if

- [(4.1)](#4.1)

its lookup context, if it is a qualified name,
is the current instantiation, and

- [(4.2)](#4.2)

lookup for it finds any member of a class that is the current instantiation

[*Example [3](#example-3)*: template <class T> class A {static const int i = 5; int n1[i]; // i refers to a member of the current instantiationint n2[A::i]; // A​::​i refers to a member of the current instantiationint n3[A<T>::i]; // A<T>​::​i refers to a member of the current instantiationint f();};

template <class T> int A<T>::f() {return i; // i refers to a member of the current instantiation} â *end example*]

A qualified or unqualified name names a [*dependent member of the current instantiation*](#def:current_instantiation,dependent_member_of_the "13.8.3.2 Dependent types [temp.dep.type]") if it is a
member of the current instantiation that, when looked up, refers to at least
one member declaration
(including a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") whose terminal name is dependent)
of a class that is the current instantiation[.](#4.sentence-2)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5505)

A qualified name ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup")) is dependent if

- [(5.1)](#5.1)

it is a [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]") whose [*conversion-type-id*](class.conv.fct#nt:conversion-type-id "11.4.8.3 Conversion functions [class.conv.fct]") is dependent, or

- [(5.2)](#5.2)

its lookup context is dependent and is not the current instantiation, or

- [(5.3)](#5.3)

its lookup context is the current instantiation and
it is operator=,[117](#footnote-117 "Every instantiation of a class template declares a different set of assignment operators.") or

- [(5.4)](#5.4)

its lookup context is the current instantiation and
has at least one dependent base class, and
qualified name lookup for the name finds nothing ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup"))[.](#5.sentence-1)

[*Example [4](#example-4)*: struct A {using B = int;
 A f();};struct C : A {};template<class T>void g(T t) {decltype(t.A::f())::B i; // error: typename needed to interpret B as a type}template void g(C); // …even though A is ​::​A here â *end example*]

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5541)

If, for a given set of template arguments, a specialization of a template is
instantiated that refers to a member of the current instantiation with a
qualified name, the name is looked up in the
template instantiation context[.](#6.sentence-1)

If the result of this lookup differs from the
result of name lookup in the template definition context, name lookup is
ambiguous[.](#6.sentence-2)

[*Example [5](#example-5)*: struct A {int m;};

struct B {int m;};

template<typename T>struct C : A, T {int f() { return this->m; } // finds A​::​m in the template definition contextint g() { return m; } // finds A​::​m in the template definition context};

template int C<B>::f(); // error: finds both A​::​m and B​::​mtemplate int C<B>::g(); // OK, transformation to class member access syntax// does not occur in the template definition context; see [[expr.prim.id.general]](expr.prim.id.general "7.5.5.1 General") â *end example*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5570)

An initializer is dependent if
any constituent expression ([[intro.execution]](intro.execution "6.10.1 Sequential execution")) of the initializer
is type-dependent[.](#7.sentence-1)

A placeholder type ([[dcl.spec.auto.general]](dcl.spec.auto.general "9.2.9.7.1 General")) is dependent if
it designates a type deduced from a dependent initializer[.](#7.sentence-2)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5577)

A placeholder for a deduced class type ([[dcl.type.class.deduct]](dcl.type.class.deduct "9.2.9.8 Deduced class template specialization types"))
is dependent if

- [(8.1)](#8.1)

it has a dependent initializer, or

- [(8.2)](#8.2)

it refers to an alias template
that is a member of the current instantiation and
whose [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]") is dependent after
class template argument deduction ([[over.match.class.deduct]](over.match.class.deduct "12.2.2.9 Class template argument deduction"))
and substitution ([[temp.alias]](temp.alias "13.7.8 Alias templates"))[.](#8.sentence-1)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5591)

[*Example [6](#example-6)*: template<class T, class V>struct S { S(T); };

template<class U>struct A {template<class T> using X = S<T, U>; template<class T> using Y = S<T, int>; void f() {new X(1); // dependentnew Y(1); // not dependent}}; â *end example*]

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5609)

A type is dependent if it is

- [(10.1)](#10.1)

a template parameter,

- [(10.2)](#10.2)

denoted by a dependent (qualified) name,

- [(10.3)](#10.3)

a nested class or enumeration that is a direct member of
a class that is the current instantiation,

- [(10.4)](#10.4)

a cv-qualified type where the cv-unqualified type is dependent,

- [(10.5)](#10.5)

a compound type constructed from any dependent type,

- [(10.6)](#10.6)

an array type whose element type is dependent or whose
bound (if any) is value-dependent,

- [(10.7)](#10.7)

a function type whose parameters include one or more function parameter packs,

- [(10.8)](#10.8)

a function type whose exception specification is value-dependent,

- [(10.9)](#10.9)

denoted by a dependent placeholder type,

- [(10.10)](#10.10)

denoted by a dependent placeholder for a deduced class type,

- [(10.11)](#10.11)

denoted by a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") in which either the template name is a template parameter or any of the
template arguments is dependent ([[temp.dep.temp]](temp.dep.temp "13.8.3.7 Dependent template arguments")),[118](#footnote-118 "This includes an injected-class-name ([class.pre]) of a class template used without a template-argument-list.")

- [(10.12)](#10.12)

a [*pack-index-specifier*](dcl.type.pack.index#nt:pack-index-specifier "9.2.9.4 Pack indexing specifier [dcl.type.pack.index]"),

- [(10.13)](#10.13)

denoted by decltype([*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]")),
where [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") is [type-dependent](temp.dep.expr "13.8.3.3 Type-dependent expressions [temp.dep.expr]"), or

- [(10.14)](#10.14)

denoted by a [*splice-type-specifier*](dcl.type.splice#nt:splice-type-specifier "9.2.9.9 Type splicing [dcl.type.splice]") in which either
the [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") is dependent ([[temp.dep.splice]](temp.dep.splice "13.8.3.5 Dependent splice specifiers"))[.](#10.sentence-1)

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L5651)

[*Note [3](#note-3)*:

Because typedefs do not introduce new types, but
instead simply refer to other types, a name that refers to a
typedef that is a member of the current instantiation is dependent
only if the type referred to is dependent[.](#11.sentence-1)

â *end note*]

[117)](#footnote-117)[117)](#footnoteref-117)

Every instantiation of a class template declares
a different set of assignment operators[.](#footnote-117.sentence-1)

[118)](#footnote-118)[118)](#footnoteref-118)

This includes an injected-class-name ([[class.pre]](class.pre "11.1 Preamble")) of a class template
used without a [*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]")[.](#footnote-118.sentence-1)
