[temp.dep]

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

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

### 13.8.3 Dependent names [temp.dep]

#### [13.8.3.1](#general) General [[temp.dep.general]](temp.dep.general)

[1](#general-1)

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

Inside a template, some constructs have semantics which may differ from one
instantiation to another[.](#general-1.sentence-1)

Such a construct[*depends*](#def:name,dependent "13.8.3.1 General [temp.dep.general]") on the template parameters[.](#general-1.sentence-2)

In particular, types and expressions may depend on the type
and/or
value of
template parameters (as determined by the template arguments) and this determines
the context for name lookup for certain names[.](#general-1.sentence-3)

An expression may be[*type-dependent*](#def:expression,type-dependent "13.8.3.1 General [temp.dep.general]") (that is, its type may depend on a template parameter) or[*value-dependent*](#def:expression,value-dependent "13.8.3.1 General [temp.dep.general]") (that is, its value when evaluated as a constant expression ([[expr.const]](expr.const "7.7 Constant expressions"))
may depend on a template parameter)
as described below[.](#general-1.sentence-4)

[2](#general-2)

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

A [*dependent call*](#def:call,dependent "13.8.3.1 General [temp.dep.general]") is an expression,
possibly formed as a non-member candidate for an operator ([[over.match.oper]](over.match.oper "12.2.2.3 Operators in expressions")),
of the form:

[*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]")opt )

where the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") is an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") and

- [(2.1)](#general-2.1)

any of the expressions in the [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]") is a pack
expansion ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates")), or

- [(2.2)](#general-2.2)

any of the expressions
or [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]")*s* in the[*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]") is [type-dependent](#expr "13.8.3.3 Type-dependent expressions [temp.dep.expr]"), or

- [(2.3)](#general-2.3)

the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") is a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") in which any of the template arguments depends
on a template parameter[.](#general-2.sentence-1)

The component name of an [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names"))
is dependent if

- [(2.4)](#general-2.4)

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

- [(2.5)](#general-2.5)

it is operator= and
the current class is a templated entity, or

- [(2.6)](#general-2.6)

the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") is
the [*postfix-expression*](expr.post.general#nt:postfix-expression "7.6.1.1 General [expr.post.general]") in a dependent call[.](#general-2.sentence-2)

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

Such names
are looked up only at the point of the template instantiation ([[temp.point]](temp.point "13.8.4.1 Point of instantiation"))
in both the context of the template definition and the
context of the point of instantiation ([[temp.dep.candidate]](temp.dep.candidate "13.8.4.2 Candidate functions"))[.](#general-2.sentence-3)

â *end note*]

[3](#general-3)

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

[*Example [1](#general-example-1)*: template<class T> struct X : B<T> {typename T::A* pa; void f(B<T>* pb) {static int i = B<T>::i;
 pb->j++; }};

The base class nameB<T>,
the type nameT​::​A,
the namesB<T>​::​i andpb->j explicitly depend on the[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")[.](#general-3.sentence-1)

â *end example*]

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

[1](#type-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)](#type-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)](#type-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)](#type-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)](#type-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)](#type-1.5)

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

[2](#type-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[.](#type-2.sentence-1)

A template argument is equivalent to a type template parameter
if it denotes the same type[.](#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[.](#type-2.sentence-3)

A variable is equivalent to a template parameter if

- [(2.1)](#type-2.1)

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

- [(2.2)](#type-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[.](#type-2.sentence-4)

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

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

â *end note*]

[*Example [1](#type-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](#type-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[.](#type-3.sentence-1)

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

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

[*Example [2](#type-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](#type-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)](#type-4.1)

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

- [(4.2)](#type-4.2)

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

[*Example [3](#type-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[.](#type-4.sentence-2)

[5](#type-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)](#type-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)](#type-5.2)

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

- [(5.3)](#type-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)](#type-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"))[.](#type-5.sentence-1)

[*Example [4](#type-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](#type-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[.](#type-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[.](#type-6.sentence-2)

[*Example [5](#type-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](#type-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[.](#type-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[.](#type-7.sentence-2)

[8](#type-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)](#type-8.1)

it has a dependent initializer, or

- [(8.2)](#type-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"))[.](#type-8.sentence-1)

[9](#type-9)

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

[*Example [6](#type-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](#type-10)

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

A type is dependent if it is

- [(10.1)](#type-10.1)

a template parameter,

- [(10.2)](#type-10.2)

denoted by a dependent (qualified) name,

- [(10.3)](#type-10.3)

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

- [(10.4)](#type-10.4)

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

- [(10.5)](#type-10.5)

a compound type constructed from any dependent type,

- [(10.6)](#type-10.6)

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

- [(10.7)](#type-10.7)

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

- [(10.8)](#type-10.8)

a function type whose exception specification is value-dependent,

- [(10.9)](#type-10.9)

denoted by a dependent placeholder type,

- [(10.10)](#type-10.10)

denoted by a dependent placeholder for a deduced class type,

- [(10.11)](#type-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 "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)](#type-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)](#type-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](#expr "13.8.3.3 Type-dependent expressions [temp.dep.expr]"), or

- [(10.14)](#type-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]](#splice "13.8.3.5 Dependent splice specifiers"))[.](#type-10.sentence-1)

[11](#type-11)

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

[*Note [3](#type-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[.](#type-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)

#### [13.8.3.3](#expr) Type-dependent expressions [[temp.dep.expr]](temp.dep.expr)

[1](#expr-1)

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

Except as described below, an expression is type-dependent if any
subexpression is type-dependent[.](#expr-1.sentence-1)

[2](#expr-2)

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

this is type-dependent if the current class ([[expr.prim.this]](expr.prim.this "7.5.3 This")) is
dependent ([[temp.dep.type]](#type "13.8.3.2 Dependent types"))[.](#expr-2.sentence-1)

[3](#expr-3)

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

An [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is type-dependent
if it is a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") that is not a concept-id and is dependent;
or if its terminal name is

- [(3.1)](#expr-3.1)

associated by name lookup with one or more declarations
declared with a dependent type,

- [(3.2)](#expr-3.2)

associated by name lookup with
a constant template parameter
declared with a type
that contains a placeholder type ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7 Placeholder type specifiers")),

- [(3.3)](#expr-3.3)

associated by name lookup with
a variable declared with a type that contains a placeholder type ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7 Placeholder type specifiers"))
where the initializer is type-dependent,

- [(3.4)](#expr-3.4)

associated by name lookup with one or more
declarations of member functions of a class that is the current instantiation
declared with a return type that contains a placeholder type,

- [(3.5)](#expr-3.5)

associated by name lookup with
a structured binding declaration ([[dcl.struct.bind]](dcl.struct.bind "9.7 Structured binding declarations")) whose[*brace-or-equal-initializer*](dcl.init.general#nt:brace-or-equal-initializer "9.5.1 General [dcl.init.general]") is type-dependent,

- [(3.6)](#expr-3.6)

associated by name lookup with a pack,
  [*Example [1](#expr-example-1)*: struct C { };

    void g(...); // #1template <typename T>void f() { C arr[1]; auto [...e] = arr;
 g(e...); // calls #2}void g(C); // #2int main() { f<int>();} â *end example*]

- [(3.7)](#expr-3.7)

associated by name lookup with
an entity captured by copy ([[expr.prim.lambda.capture]](expr.prim.lambda.capture "7.5.6.3 Captures"))
in a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") that has an explicit object parameter whose type is dependent ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")),

- [(3.8)](#expr-3.8)

the[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")__func__ ([[dcl.fct.def.general]](dcl.fct.def.general "9.6.1 General")), where any enclosing function is a
template, a member of a class template, or a generic lambda,

- [(3.9)](#expr-3.9)

associated by name lookup
with a result binding ([[dcl.contract.res]](dcl.contract.res "9.4.2 Referring to the result object")) of a function
whose return type is dependent,

- [(3.10)](#expr-3.10)

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

- [(3.11)](#expr-3.11)

a name N introduced by the [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1 Preamble [stmt.pre]") of an expansion statement S if the type specified for N contains a placeholder type and either
  * [(3.11.1)](#expr-3.11.1)

the [*expansion-initializer*](stmt.expand#nt:expansion-initializer "8.7 Expansion statements [stmt.expand]") of S is type-dependent or

  * [(3.11.2)](#expr-3.11.2)

S is not an iterating expansion statement, or

- [(3.12)](#expr-3.12)

dependent

or if it names a dependent member of the current instantiation that is a static
data member of type
âarray of unknown bound of Tâ for some T ([[temp.static]](temp.static "13.7.2.5 Static data members of class templates"))[.](#expr-3.sentence-1)

Expressions of the following forms are type-dependent only if the type
specified by the[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]"),[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]"),[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]"),
or[*new-type-id*](expr.new#nt:new-type-id "7.6.2.8 New [expr.new]") is dependent, even if any subexpression is type-dependent:

[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]")opt )  
[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]")  
[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]")opt )  
[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]") [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]")  
::opt new [*new-placement*](expr.new#nt:new-placement "7.6.2.8 New [expr.new]")opt [*new-type-id*](expr.new#nt:new-type-id "7.6.2.8 New [expr.new]") [*new-initializer*](expr.new#nt:new-initializer "7.6.2.8 New [expr.new]")opt  
::opt new [*new-placement*](expr.new#nt:new-placement "7.6.2.8 New [expr.new]")opt ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) [*new-initializer*](expr.new#nt:new-initializer "7.6.2.8 New [expr.new]")opt  
dynamic_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") )  
static_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") )  
const_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") )  
reinterpret_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") )  
( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]")

[4](#expr-4)

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

Expressions of the following forms are never type-dependent (because the type
of the expression cannot be dependent):

[*literal*](lex.literal.kinds#nt:literal "5.13.1 Kinds of literals [lex.literal.kinds]")  
sizeof [*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1 General [expr.unary.general]")  
sizeof ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") )  
sizeof ... ( [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") )  
alignof ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") )  
typeid ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") )  
typeid ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") )  
::opt delete [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]")  
::opt delete [ ] [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]")  
throw [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19 Assignment and compound assignment operators [expr.assign]")opt  
noexcept ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") )  
[*requires-expression*](expr.prim.req.general#nt:requires-expression "7.5.8.1 General [expr.prim.req.general]")  
[*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]")

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

For the standard library macro offsetof,
see [[support.types]](support.types "17.2 Common definitions")[.](#expr-4.sentence-2)

â *end note*]

[5](#expr-5)

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

A [class member access expression](expr.ref "7.6.1.5 Class member access [expr.ref]") is
type-dependent if
the terminal name of its [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]"), if any, is dependent or
the expression refers to a member of the current instantiation and
the type of the referenced member is dependent[.](#expr-5.sentence-1)

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

In an expression of the formx.y orxp->y the type of the expression is usually the type of the membery of the class ofx (or the class pointed to byxp)[.](#expr-5.sentence-2)

However, ifx orxp refers to a dependent type that is not the current instantiation,
the type ofy is always dependent[.](#expr-5.sentence-3)

â *end note*]

[6](#expr-6)

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

A [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]") is type-dependent if any element is
type-dependent or is a pack expansion[.](#expr-6.sentence-1)

[7](#expr-7)

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

A [*fold-expression*](expr.prim.fold#nt:fold-expression "7.5.7 Fold expressions [expr.prim.fold]") is type-dependent[.](#expr-7.sentence-1)

[8](#expr-8)

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

A [*pack-index-expression*](expr.prim.pack.index#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]") is type-dependent
if its [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is type-dependent[.](#expr-8.sentence-1)

[9](#expr-9)

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

A [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") is type-dependent
if its [*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]](#splice "13.8.3.5 Dependent splice specifiers"))[.](#expr-9.sentence-1)

#### [13.8.3.4](#constexpr) Value-dependent expressions [[temp.dep.constexpr]](temp.dep.constexpr)

[1](#constexpr-1)

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

Except as described below, an expression used in a context where a
constant expression is required is value-dependent if any
subexpression is value-dependent[.](#constexpr-1.sentence-1)

[2](#constexpr-2)

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

An[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is value-dependent if

- [(2.1)](#constexpr-2.1)

it is a concept-id and
its [*concept-name*](temp.concept#nt:concept-name "13.7.9 Concept definitions [temp.concept]") is dependent or
any of its arguments are dependent ([[temp.dep.temp]](#temp "13.8.3.7 Dependent template arguments")),

- [(2.2)](#constexpr-2.2)

it is type-dependent,

- [(2.3)](#constexpr-2.3)

it is the name of a constant template parameter,

- [(2.4)](#constexpr-2.4)

it is a name introduced by the [*for-range-declaration*](stmt.pre#nt:for-range-declaration "8.1 Preamble [stmt.pre]") of an expansion statement ([[stmt.expand]](stmt.expand "8.7 Expansion statements")),

- [(2.5)](#constexpr-2.5)

it names a static data member that is a dependent member of the current
instantiation and is not initialized in a [*member-declarator*](class.mem.general#nt:member-declarator "11.4.1 General [class.mem.general]"),

- [(2.6)](#constexpr-2.6)

it names a static member function that is a dependent member of the current
instantiation, or

- [(2.7)](#constexpr-2.7)

it names a potentially-constant variable ([[expr.const]](expr.const "7.7 Constant expressions"))
that is initialized with an expression that is value-dependent[.](#constexpr-2.sentence-1)

Expressions of the following form are value-dependent if the[*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1 General [expr.unary.general]") or [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") is type-dependent or the[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") is dependent:

sizeof [*unary-expression*](expr.unary.general#nt:unary-expression "7.6.2.1 General [expr.unary.general]")  
sizeof ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") )  
typeid ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") )  
typeid ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") )  
alignof ( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") )

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

For the standard library macro offsetof,
see [[support.types]](support.types "17.2 Common definitions")[.](#constexpr-2.sentence-3)

â *end note*]

[3](#constexpr-3)

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

Expressions of the following form are value-dependent if either the[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]"),[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]"), or[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]") is dependent or the[*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") or[*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") is value-dependent or
any [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") in the [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]") is value-dependent or
any [*assignment-expression*](expr.assign#nt:assignment-expression "7.6.19 Assignment and compound assignment operators [expr.assign]") in the [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]") is value-dependent:

[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]")opt )  
[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]") ( [*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]")opt )  
[*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]")  
[*typename-specifier*](temp.res.general#nt:typename-specifier "13.8.1 General [temp.res.general]") [*braced-init-list*](dcl.init.general#nt:braced-init-list "9.5.1 General [dcl.init.general]")  
static_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") )  
const_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") )  
reinterpret_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") )  
dynamic_cast < [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") > ( [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") )  
( [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") ) [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]")

[4](#constexpr-4)

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

Expressions of the following form are value-dependent:

sizeof ... ( [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") )  
[*fold-expression*](expr.prim.fold#nt:fold-expression "7.5.7 Fold expressions [expr.prim.fold]")

unless the [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") is a structured binding pack
whose initializer is not dependent[.](#constexpr-4.sentence-1)

[5](#constexpr-5)

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

A [*noexcept-expression*](expr.unary.noexcept#nt:noexcept-expression "7.6.2.7 noexcept operator [expr.unary.noexcept]") ([[expr.unary.noexcept]](expr.unary.noexcept "7.6.2.7 noexcept operator"))
is value-dependent if
its [*expression*](expr.comma#nt:expression "7.6.20 Comma operator [expr.comma]") involves a template parameter[.](#constexpr-5.sentence-1)

[6](#constexpr-6)

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

An expression of the form &[*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") where the[*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") names a dependent member of the current
instantiation is value-dependent[.](#constexpr-6.sentence-1)

An expression of the form &[*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") is also value-dependent if evaluating [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") as a [core constant expression](expr.const#def:expression,core_constant "7.7 Constant expressions [expr.const]") succeeds and
the result of the evaluation refers to a templated entity
that is an object with static or thread storage duration or a member function[.](#constexpr-6.sentence-2)

[7](#constexpr-7)

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

A [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") is value-dependent if

- [(7.1)](#constexpr-7.1)

it is of the form ^^[*reflection-name*](expr.reflect#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]") and
the [*reflection-name*](expr.reflect#nt:reflection-name "7.6.2.10 The reflection operator [expr.reflect]")
  * [(7.1.1)](#constexpr-7.1.1)

is a dependent qualified name,

  * [(7.1.2)](#constexpr-7.1.2)

is a dependent [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]"),

  * [(7.1.3)](#constexpr-7.1.3)

is the name of a template parameter, or

  * [(7.1.4)](#constexpr-7.1.4)

names a dependent member of the current instantiation ([[temp.dep.type]](#type "13.8.3.2 Dependent types")),

- [(7.2)](#constexpr-7.2)

it is of the form ^^[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") and
the [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") denotes a dependent type, or

- [(7.3)](#constexpr-7.3)

it is of the form ^^[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") and
the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") is value-dependent[.](#constexpr-7.sentence-1)

[8](#constexpr-8)

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

A [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]") is value-dependent
if its [*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]](#splice "13.8.3.5 Dependent splice specifiers"))[.](#constexpr-8.sentence-1)

#### [13.8.3.5](#splice) Dependent splice specifiers [[temp.dep.splice]](temp.dep.splice)

[1](#splice-1)

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

A [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") is dependent
if its converted [*constant-expression*](expr.const#nt:constant-expression "7.7 Constant expressions [expr.const]") is value-dependent[.](#splice-1.sentence-1)

A [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") is dependent
if its [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") is dependent or
if any of its template arguments are dependent[.](#splice-1.sentence-2)

A [*splice-scope-specifier*](expr.prim.id.qual#nt:splice-scope-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") is dependent
if its [*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[.](#splice-1.sentence-3)

[2](#splice-2)

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

[*Example [1](#splice-example-1)*: template<auto T, auto NS>void fn() {using a = [:T:]<1>; // [:T:]<1> is dependent because [:T:] is dependentstatic_assert([:NS:]::template TCls<1>::v == a::v); // [:NS:] is dependent}namespace N {template <auto V> struct TCls { static constexpr int v = V; };}int main() { fn<^^N::TCls, ^^N>();} â *end example*]

[3](#splice-3)

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

[*Example [2](#splice-example-2)*: template<template<class> class X>struct S {[:^^X:]<int, float> m;};

template<class> struct V1 {};template<class, class = int> struct V2 {};

S<V1> s1; // error: V1<int, float> has too many template arguments S<V2> s2; // OK â *end example*]

#### [13.8.3.6](#namespace) Dependent namespaces [[temp.dep.namespace]](temp.dep.namespace)

[1](#namespace-1)

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

A namespace alias is dependent
if it is introduced by a [*namespace-alias-definition*](namespace.alias#nt:namespace-alias-definition "9.9.3 Namespace alias [namespace.alias]") whose [*qualified-namespace-specifier*](namespace.alias#nt:qualified-namespace-specifier "9.9.3 Namespace alias [namespace.alias]") (if any) is
a dependent qualified name or
whose [*splice-specifier*](basic.splice#nt:splice-specifier "6.6 Splice specifiers [basic.splice]") (if any) is dependent[.](#namespace-1.sentence-1)

A [*namespace-name*](namespace.def.general#nt:namespace-name "9.9.2.1 General [namespace.def.general]") is dependent
if it names a dependent namespace alias[.](#namespace-1.sentence-2)

[2](#namespace-2)

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

[*Example [1](#namespace-example-1)*: template<std::meta::info R>int fn() {namespace Alias = [:R:]; // [:R:] is dependentreturn typename Alias::T{}; // Alias is dependent}namespace NS {using T = int;}int a = fn<^^NS>(); â *end example*]

#### [13.8.3.7](#temp) Dependent template arguments [[temp.dep.temp]](temp.dep.temp)

[1](#temp-1)

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

A type[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") is dependent if the type it specifies is dependent[.](#temp-1.sentence-1)

[2](#temp-2)

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

A constant[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") is dependent if its type is dependent or the constant
expression it specifies is value-dependent[.](#temp-2.sentence-1)

[3](#temp-3)

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

Furthermore, a constant[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") is dependent if the corresponding constant template parameter
is of reference or pointer type and the [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") designates or points to a member of the current instantiation or a member of
a dependent type[.](#temp-3.sentence-1)

[4](#temp-4)

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

A template argument is also dependent if it is a pack expansion[.](#temp-4.sentence-1)

[5](#temp-5)

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

A template template parameter is dependent if
it names a template parameter or
its terminal name is dependent[.](#temp-5.sentence-1)
