[temp.res]

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

## 13.8 Name resolution [temp.res]

### [13.8.1](#general) General [[temp.res.general]](temp.res.general)

[1](#general-1)

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

A name that appears in a declaration D of a template T is looked up
from where it appears
in an unspecified declaration of T that either is D itself or is reachable from D and
from which no other declaration of T that contains the usage of the name is reachable[.](#general-1.sentence-1)

If the name is dependent (as specified in [[temp.dep]](#temp.dep "13.8.3 Dependent names")),
it is looked up for each specialization (after substitution)
because the lookup depends on a template parameter[.](#general-1.sentence-2)

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

Some dependent names are also looked up during parsing to determine
that they are dependent or to interpret following < tokens[.](#general-1.sentence-3)

Uses of other names might be type-dependent or
value-dependent ([[temp.dep.expr]](#temp.dep.expr "13.8.3.3 Type-dependent expressions"), [[temp.dep.constexpr]](#temp.dep.constexpr "13.8.3.4 Value-dependent expressions"))[.](#general-1.sentence-4)

A [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") is never dependent in a specialization and
is therefore replaced during lookup for that specialization ([[basic.lookup]](basic.lookup "6.5 Name lookup"))[.](#general-1.sentence-5)

â *end note*]

[*Example [1](#general-example-1)*: struct A { operator int(); };template<class B, class T>struct D : B { T get() { return operator T(); } // [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3 Conversion functions [class.conv.fct]") is dependent};int f(D<A, int> d) { return d.get(); } // OK, lookup finds A​::​operator int â *end example*]

[*Example [2](#general-example-2)*: void f(char);

template<class T> void g(T t) { f(1); // f(char) f(T(1)); // dependent f(t); // dependent dd++; // not dependent; error: declaration for dd not found}enum E { e };void f(E);

double dd;void h() { g(e); // will cause one call of f(char) followed by two calls of f(E) g('a'); // will cause three calls of f(char)} â *end example*]

[*Example [3](#general-example-3)*: struct A {struct B { /* ... */ }; int a; int Y;};

int a;

template<class T> struct Y : T {struct B { /* ... */ };
 B b; // The B defined in Yvoid f(int i) { a = i; } // ​::​a Y* p; // Y<T>};

Y<A> ya;

The members A​::​B, A​::​a, and A​::​Y of the template argument A do not affect the binding of names in Y<A>[.](#general-1.sentence-6)

â *end example*]

[2](#general-2)

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

If the validity or meaning of the program would be changed by
considering a default argument or default template argument
introduced in a declaration that is reachable from
the point of instantiation of a specialization ([[temp.point]](#temp.point "13.8.4.1 Point of instantiation"))
but is not found by lookup for the specialization,
the program is ill-formed, no diagnostic required[.](#general-2.sentence-1)

[typename-specifier:](#nt:typename-specifier "13.8.1 General [temp.res.general]")  
typename [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")  
typename [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") templateopt [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")

[3](#general-3)

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

The component names of a [*typename-specifier*](#nt:typename-specifier "13.8.1 General [temp.res.general]") are
its [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") (if any) and
those of its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") and[*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") (if any)[.](#general-3.sentence-1)

A [*typename-specifier*](#nt:typename-specifier "13.8.1 General [temp.res.general]") denotes the type or class template
denoted by the [*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") ([[dcl.type.simple]](dcl.type.simple "9.2.9.3 Simple type specifiers"))
formed by omitting the keyword typename[.](#general-3.sentence-2)

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

The usual qualified name lookup ([[basic.lookup.qual]](basic.lookup.qual "6.5.5 Qualified name lookup")) applies
even in the presence of typename[.](#general-3.sentence-3)

â *end note*]

[*Example [4](#general-example-4)*: struct A {struct X { }; int X;};struct B {struct X { };};template<class T> void f(T t) {typename T::X x;}void foo() { A a;
 B b;
 f(b); // OK, T​::​X refers to B​::​X f(a); // error: T​::​X refers to the data member A​::​X not the struct A​::​X} â *end example*]

[4](#general-4)

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

A [*type-only context*](#def:context,type-only "13.8.1 General [temp.res.general]") is defined as follows:
A qualified or unqualified name is said to be in
a type-only context if it is the terminal name of

- [(4.1)](#general-4.1)

a[*typename-specifier*](#nt:typename-specifier "13.8.1 General [temp.res.general]"),[*type-requirement*](expr.prim.req.type#nt:type-requirement "7.5.8.3 Type requirements [expr.prim.req.type]"),[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]"),[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]"),[*class-or-decltype*](class.derived.general#nt:class-or-decltype "11.7.1 General [class.derived.general]"),[*using-enum-declarator*](enum.udecl#nt:using-enum-declarator "9.8.2 The using enum declaration [enum.udecl]"),
or

- [(4.2)](#general-4.2)

a [*simple-type-specifier*](dcl.type.simple#nt:simple-type-specifier "9.2.9.3 Simple type specifiers [dcl.type.simple]") of a [*friend-type-specifier*](class.mem.general#nt:friend-type-specifier "11.4.1 General [class.mem.general]"), or

- [(4.3)](#general-4.3)

a [*type-specifier*](dcl.type.general#nt:type-specifier "9.2.9.1 General [dcl.type.general]") of a
  * [(4.3.1)](#general-4.3.1)

[*new-type-id*](expr.new#nt:new-type-id "7.6.2.8 New [expr.new]"),

  * [(4.3.2)](#general-4.3.2)

[*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]"),

  * [(4.3.3)](#general-4.3.3)

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

  * [(4.3.4)](#general-4.3.4)

[*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]"),

  * [(4.3.5)](#general-4.3.5)

default argument of a [*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]"), or

  * [(4.3.6)](#general-4.3.6)

[*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") of astatic_cast,const_cast,reinterpret_cast, ordynamic_cast, or

- [(4.4)](#general-4.4)

a [*decl-specifier*](dcl.spec.general#nt:decl-specifier "9.2.1 General [dcl.spec.general]") of the [*decl-specifier-seq*](dcl.spec.general#nt:decl-specifier-seq "9.2.1 General [dcl.spec.general]") of a
  * [(4.4.1)](#general-4.4.1)

[*simple-declaration*](dcl.pre#nt:simple-declaration "9.1 Preamble [dcl.pre]") or [*function-definition*](dcl.fct.def.general#nt:function-definition "9.6.1 General [dcl.fct.def.general]") in namespace scope,

  * [(4.4.2)](#general-4.4.2)

[*member-declaration*](class.mem.general#nt:member-declaration "11.4.1 General [class.mem.general]"),

  * [(4.4.3)](#general-4.4.3)

[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") in a [*member-declaration*](class.mem.general#nt:member-declaration "11.4.1 General [class.mem.general]"),[116](#footnote-116 "This includes friend function declarations.") unless that [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") appears in a default argument,

  * [(4.4.4)](#general-4.4.4)

[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") in a [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") of a function or function template declaration
whose [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1 General [dcl.decl.general]") is qualified,
unless that [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") appears in a default argument,

  * [(4.4.5)](#general-4.4.5)

[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") in a [*lambda-declarator*](expr.prim.lambda.general#nt:lambda-declarator "7.5.6.1 General [expr.prim.lambda.general]") or [*requirement-parameter-list*](expr.prim.req.general#nt:requirement-parameter-list "7.5.8.1 General [expr.prim.req.general]"),
unless that [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") appears in a default argument, or

  * [(4.4.6)](#general-4.4.6)

[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") of a [*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]") (which necessarily declares a constant template parameter)[.](#general-4.sentence-1)

A [*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]") ([[basic.splice]](basic.splice "6.6 Splice specifiers"))
is said to be in a type-only context
if a hypothetical qualified name appearing in the same position
would be in a type-only context[.](#general-4.sentence-2)

[*Example [5](#general-example-5)*: template<class T> T::R f(); // OK, return type of a function declaration at global scopetemplate<class T> void f(T::R); // ill-formed, no diagnostic required: attempt to declare// a void variable templateenum class Enum { A, B, C };template<class T> struct S {using Ptr = PtrTraits<T>::Ptr; // OK, in a [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]")using Alias = [:^^int:]; // OK, in a [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]") T::R f(T::P p) { // OK, class scopereturn static_cast<T::R>(p); // OK, [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]") of a static_cast}auto g() -> S<T*>::Ptr; // OK, [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]")auto h() -> [:^^S:]<T*>; // OK, [*trailing-return-type*](dcl.decl.general#nt:trailing-return-type "9.3.1 General [dcl.decl.general]")using enum [:^^Enum:]; // OK, [*using-enum-declarator*](enum.udecl#nt:using-enum-declarator "9.8.2 The using enum declaration [enum.udecl]")};template<typename T> void f() {void (*pf)(T::X); // variable pf of type void* initialized with T​::​Xvoid g(T::X); // error: T​::​X at block scope does not denote a type// (attempt to declare a void variable)} â *end example*]

[5](#general-5)

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

A [*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") whose terminal name is dependent and that is in a type-only context
is considered to denote a type[.](#general-5.sentence-1)

A name
that refers to a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") whose terminal name is dependent
is interpreted as a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") if the [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]") uses the keyword typename[.](#general-5.sentence-2)

[*Example [6](#general-example-6)*: template <class T> void f(int i) { T::x * i; // expression, not the declaration of a variable i}struct Foo {typedef int x;};

struct Bar {static int const x = 5;};

int main() { f<Bar>(1); // OK f<Foo>(1); // error: Foo​::​x is a type} â *end example*]

[6](#general-6)

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

The validity of a templated entity may be checked prior to any instantiation[.](#general-6.sentence-1)

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

Knowing which names are type names allows the syntax of every template
to be checked in this way[.](#general-6.sentence-2)

â *end note*]

The program is ill-formed, no diagnostic required, if

- [(6.1)](#general-6.1)

no valid specialization,
ignoring [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1 Preamble [dcl.pre]")s that fail ([[dcl.pre]](dcl.pre "9.1 Preamble")),
can be generated for a templated entity
or a substatement of a constexpr if statement ([[stmt.if]](stmt.if "8.5.2 The if statement"))
within a templated entity
and the innermost enclosing template is not instantiated, or

- [(6.2)](#general-6.2)

no valid specialization,
ignoring [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1 Preamble [dcl.pre]")s that fail,
can be generated for the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of an expansion statement and there is no instantiation of it, or

- [(6.3)](#general-6.3)

no valid specialization,
ignoring [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1 Preamble [dcl.pre]")s that fail,
can be generated for a default [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") and
the default [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") is not used in any instantiation, or

- [(6.4)](#general-6.4)

no specialization of an alias template ([[temp.alias]](temp.alias "13.7.8 Alias templates")) is valid and
no specialization of the alias template is named in the program, or

- [(6.5)](#general-6.5)

any [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") in the program, introduced or otherwise,
has (in its normal form) an atomic constraint A where
no satisfaction check of A could be well-formed and
no satisfaction check of A is performed, or

- [(6.6)](#general-6.6)

every valid specialization of a variadic template requires an empty template
parameter pack, or

- [(6.7)](#general-6.7)

a hypothetical instantiation of a templated entity
immediately following its definition
would be ill-formed
due to a construct
(other than a [*static_assert-declaration*](dcl.pre#nt:static_assert-declaration "9.1 Preamble [dcl.pre]") that fails)
that does not depend on a template parameter, or

- [(6.8)](#general-6.8)

the interpretation of such a construct
in the hypothetical instantiation
is different from
the interpretation of the corresponding construct
in any actual instantiation of the templated entity[.](#general-6.sentence-3)

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

This can happen in situations including the following:

- [(6.9)](#general-6.9)

a type used in a non-dependent name is incomplete at the point at which a
template is defined but is complete at the point at which an instantiation is
performed, or

- [(6.10)](#general-6.10)

lookup for a name in the template definition found a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]"),
but the lookup in the corresponding scope in the instantiation
does not find any declarations because the [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]") was a pack expansion and the corresponding pack is empty, or

- [(6.11)](#general-6.11)

an instantiation uses a default argument or default template argument
that had not been defined at the point at which the template was defined, or

- [(6.12)](#general-6.12)

[constant expression evaluation](expr.const "7.7 Constant expressions [expr.const]") within the template
instantiation uses
  * [(6.12.1)](#general-6.12.1)

the value of a const object of integral or unscoped enumeration type or

  * [(6.12.2)](#general-6.12.2)

the value of a constexpr object or

  * [(6.12.3)](#general-6.12.3)

the value of a reference or

  * [(6.12.4)](#general-6.12.4)

the definition of a constexpr function,

and that entity was not defined when the template was defined, or

- [(6.13)](#general-6.13)

a class template specialization or variable template specialization that
is specified by a non-dependent [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") is used by
the template, and either it is instantiated from a partial specialization that
was not defined when the template was defined or it names an explicit
specialization that was not declared when the template was defined[.](#general-6.sentence-4)

â *end note*]

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

If a template is instantiated, errors will be diagnosed according
to the other rules in this document[.](#general-6.sentence-5)

Exactly when these errors are diagnosed is a quality of implementation issue[.](#general-6.sentence-6)

â *end note*]

[*Example [7](#general-example-7)*: int j;template<class T> class X {void f(T t, int i, char* p) { t = i; // diagnosed if X​::​f is instantiated, and the assignment to t is an error p = i; // may be diagnosed even if X​::​f is not instantiated p = j; // may be diagnosed even if X​::​f is not instantiated X<T>::g(t); // OK X<T>::h(); // may be diagnosed even if X​::​f is not instantiated}void g(T t) {+; // may be diagnosed even if X​::​g is not instantiated}};

template<class... T> struct A {void operator++(int, T... t); // error: too many parameters};template<class... T> union X : T... { }; // error: union with base classtemplate<class... T> struct A : T..., T... { }; // error: duplicate base class â *end example*]

[7](#general-7)

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

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

For purposes of name lookup, default arguments and[*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]")*s* of function templates and default
arguments and [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]")*s* of
member functions of class templates are considered definitions ([[temp.decls]](temp.decls "13.7 Template declarations"))[.](#general-7.sentence-1)

â *end note*]

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

This includes friend function declarations[.](#footnote-116.sentence-1)

### [13.8.2](#temp.local) Locally declared names [[temp.local]](temp.local)

[1](#temp.local-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.1 Preamble"))[.](#temp.local-1.sentence-1)

The
injected-class-name can be used
as a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") or a [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]")[.](#temp.local-1.sentence-2)

When it is used with a[*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]"),
as a [*template-argument*](temp.names#nt:template-argument "13.3 Names 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.5 Elaborated type specifiers [dcl.type.elab]") of
a friend class template declaration,
it is a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") that refers to the
class template itself[.](#temp.local-1.sentence-3)

Otherwise, it is a [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") equivalent to the [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") followed by
the template argument list ([[temp.decls.general]](temp.decls.general "13.7.1 General"), [[temp.arg.general]](temp.arg.general "13.4.1 General"))
of the class template
enclosed in <>[.](#temp.local-1.sentence-4)

[2](#temp.local-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.3 Simple type specifiers [dcl.type.simple]"),
it is equivalent to the [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") followed by the[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* of the class template specialization or partial
specialization enclosed in<>[.](#temp.local-2.sentence-1)

[*Example [1](#temp.local-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](#temp.local-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.3 Names of template specializations [temp.names]") or a [*type-name*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") wherever it is named[.](#temp.local-3.sentence-1)

[*Example [2](#temp.local-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](#temp.local-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.2 Member name lookup")) can result in an ambiguity in
certain cases (for example, if it is found in more than one
base class)[.](#temp.local-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.3 Names of template specializations [temp.names]"),
the reference refers to the class template itself and not a
specialization thereof, and is not ambiguous[.](#temp.local-4.sentence-2)

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

[*Example [4](#temp.local-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](#temp.local-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[.](#temp.local-6.sentence-1)

[*Example [5](#temp.local-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](#temp.local-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.1 Preamble [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.1 Preamble [temp.pre]"))[.](#temp.local-7.sentence-1)

[*Note [1](#temp.local-note-1)*:

The scope of a class template,
including its non-dependent base classes ([[temp.dep.type]](#temp.dep.type "13.8.3.2 Dependent types"), [[class.member.lookup]](class.member.lookup "6.5.2 Member name lookup")),
is searched before its template parameter scope[.](#temp.local-7.sentence-2)

â *end note*]

[*Example [6](#temp.local-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*]

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

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

[1](#temp.dep.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[.](#temp.dep.general-1.sentence-1)

Such a construct[*depends*](#def:name,dependent "13.8.3.1 General [temp.dep.general]") on the template parameters[.](#temp.dep.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[.](#temp.dep.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[.](#temp.dep.general-1.sentence-4)

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

- [(2.3)](#temp.dep.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[.](#temp.dep.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)](#temp.dep.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)](#temp.dep.general-2.5)

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

- [(2.6)](#temp.dep.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[.](#temp.dep.general-2.sentence-2)

[*Note [1](#temp.dep.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"))[.](#temp.dep.general-2.sentence-3)

â *end note*]

[3](#temp.dep.general-3)

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

[*Example [1](#temp.dep.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]")[.](#temp.dep.general-3.sentence-1)

â *end example*]

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

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

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

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

A variable is equivalent to a template parameter if

- [(2.1)](#temp.dep.type-2.1)

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

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

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

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

â *end note*]

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

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

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

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

- [(4.2)](#temp.dep.type-4.2)

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

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

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

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

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

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

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

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

it has a dependent initializer, or

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

[9](#temp.dep.type-9)

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

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

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

A type is dependent if it is

- [(10.1)](#temp.dep.type-10.1)

a template parameter,

- [(10.2)](#temp.dep.type-10.2)

denoted by a dependent (qualified) name,

- [(10.3)](#temp.dep.type-10.3)

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

- [(10.4)](#temp.dep.type-10.4)

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

- [(10.5)](#temp.dep.type-10.5)

a compound type constructed from any dependent type,

- [(10.6)](#temp.dep.type-10.6)

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

- [(10.7)](#temp.dep.type-10.7)

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

- [(10.8)](#temp.dep.type-10.8)

a function type whose exception specification is value-dependent,

- [(10.9)](#temp.dep.type-10.9)

denoted by a dependent placeholder type,

- [(10.10)](#temp.dep.type-10.10)

denoted by a dependent placeholder for a deduced class type,

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

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

[11](#temp.dep.type-11)

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

[*Note [3](#temp.dep.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[.](#temp.dep.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](#temp.dep.expr) Type-dependent expressions [[temp.dep.expr]](temp.dep.expr)

[1](#temp.dep.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[.](#temp.dep.expr-1.sentence-1)

[2](#temp.dep.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]](#temp.dep.type "13.8.3.2 Dependent types"))[.](#temp.dep.expr-2.sentence-1)

[3](#temp.dep.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)](#temp.dep.expr-3.1)

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

- [(3.2)](#temp.dep.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)](#temp.dep.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)](#temp.dep.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)](#temp.dep.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)](#temp.dep.expr-3.6)

associated by name lookup with a pack,
  [*Example [1](#temp.dep.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)](#temp.dep.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)](#temp.dep.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)](#temp.dep.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)](#temp.dep.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)](#temp.dep.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)](#temp.dep.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)](#temp.dep.expr-3.11.2)

S is not an iterating expansion statement, or

- [(3.12)](#temp.dep.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"))[.](#temp.dep.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*](#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*](#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*](#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](#temp.dep.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](#temp.dep.expr-note-1)*:

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

â *end note*]

[5](#temp.dep.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[.](#temp.dep.expr-5.sentence-1)

[*Note [2](#temp.dep.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)[.](#temp.dep.expr-5.sentence-2)

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

â *end note*]

[6](#temp.dep.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[.](#temp.dep.expr-6.sentence-1)

[7](#temp.dep.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[.](#temp.dep.expr-7.sentence-1)

[8](#temp.dep.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[.](#temp.dep.expr-8.sentence-1)

[9](#temp.dep.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]](#temp.dep.splice "13.8.3.5 Dependent splice specifiers"))[.](#temp.dep.expr-9.sentence-1)

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

[1](#temp.dep.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[.](#temp.dep.constexpr-1.sentence-1)

[2](#temp.dep.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)](#temp.dep.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.dep.temp "13.8.3.7 Dependent template arguments")),

- [(2.2)](#temp.dep.constexpr-2.2)

it is type-dependent,

- [(2.3)](#temp.dep.constexpr-2.3)

it is the name of a constant template parameter,

- [(2.4)](#temp.dep.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)](#temp.dep.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)](#temp.dep.constexpr-2.6)

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

- [(2.7)](#temp.dep.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[.](#temp.dep.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](#temp.dep.constexpr-note-1)*:

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

â *end note*]

[3](#temp.dep.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*](#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*](#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*](#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](#temp.dep.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[.](#temp.dep.constexpr-4.sentence-1)

[5](#temp.dep.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[.](#temp.dep.constexpr-5.sentence-1)

[6](#temp.dep.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[.](#temp.dep.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[.](#temp.dep.constexpr-6.sentence-2)

[7](#temp.dep.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)](#temp.dep.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)](#temp.dep.constexpr-7.1.1)

is a dependent qualified name,

  * [(7.1.2)](#temp.dep.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)](#temp.dep.constexpr-7.1.3)

is the name of a template parameter, or

  * [(7.1.4)](#temp.dep.constexpr-7.1.4)

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

- [(7.2)](#temp.dep.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)](#temp.dep.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[.](#temp.dep.constexpr-7.sentence-1)

[8](#temp.dep.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]](#temp.dep.splice "13.8.3.5 Dependent splice specifiers"))[.](#temp.dep.constexpr-8.sentence-1)

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

[1](#temp.dep.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[.](#temp.dep.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[.](#temp.dep.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[.](#temp.dep.splice-1.sentence-3)

[2](#temp.dep.splice-2)

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

[*Example [1](#temp.dep.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](#temp.dep.splice-3)

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

[*Example [2](#temp.dep.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](#temp.dep.namespace) Dependent namespaces [[temp.dep.namespace]](temp.dep.namespace)

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

[2](#temp.dep.namespace-2)

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

[*Example [1](#temp.dep.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.dep.temp) Dependent template arguments [[temp.dep.temp]](temp.dep.temp)

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

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

[3](#temp.dep.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.dep.temp-3.sentence-1)

[4](#temp.dep.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.dep.temp-4.sentence-1)

[5](#temp.dep.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.dep.temp-5.sentence-1)

### [13.8.4](#temp.dep.res) Dependent name resolution [[temp.dep.res]](temp.dep.res)

#### [13.8.4.1](#temp.point) Point of instantiation [[temp.point]](temp.point)

[1](#temp.point-1)

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

For a function template specialization, a member function template
specialization, or a specialization for a member function or static data member
of a class template,
if the specialization is implicitly instantiated because it is referenced
from within another template specialization and
the context from which it is referenced depends on a template parameter,
the point of instantiation of the specialization is the point of instantiation
of the enclosing specialization[.](#temp.point-1.sentence-1)

Otherwise, the point of instantiation for such a specialization immediately
follows the namespace scope declaration
or definition that refers to the specialization[.](#temp.point-1.sentence-2)

[2](#temp.point-2)

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

If a function template or member function of a class template is called
in a way which uses the definition of a default argument of that function
template or member function,
the point of instantiation of the default argument is the point of
instantiation of the function template or member function specialization[.](#temp.point-2.sentence-1)

[3](#temp.point-3)

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

For a [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]") of a function template
specialization or specialization of a member function of a class template, if
the [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]") is implicitly instantiated because
it is needed by another template specialization and the context that requires
it depends on a template parameter, the point of instantiation of the[*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]") is the point of instantiation of the
specialization that requires it[.](#temp.point-3.sentence-1)

Otherwise, the point of instantiation for such
a [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]") immediately follows the namespace
scope declaration or definition that requires the[*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]")[.](#temp.point-3.sentence-2)

[4](#temp.point-4)

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

For a class template specialization, a class member template specialization,
or a specialization for a class member of a class template,
if the specialization is implicitly instantiated because it is referenced
from within another template specialization,
if the context from which the specialization is referenced depends on a
template parameter,
and if the specialization is not instantiated previous to the instantiation of
the enclosing template,
the point of instantiation is immediately before the point of instantiation of
the enclosing template[.](#temp.point-4.sentence-1)

Otherwise, the point of instantiation for such a specialization immediately
precedes the namespace scope declaration
or definition that refers to the specialization[.](#temp.point-4.sentence-2)

[5](#temp.point-5)

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

If a virtual function is implicitly instantiated, its point of instantiation
is immediately following the point of instantiation of its enclosing class
template specialization[.](#temp.point-5.sentence-1)

[6](#temp.point-6)

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

An explicit instantiation definition is an instantiation
point for the specialization or specializations specified by the explicit
instantiation[.](#temp.point-6.sentence-1)

[7](#temp.point-7)

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

A specialization for a function template, a member function template,
or of a member function or static data member of a class template may have
multiple points of instantiations within a translation unit, and in addition
to the points of instantiation described above,

- [(7.1)](#temp.point-7.1)

for any such
specialization that has a point of instantiation within the[*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]") of the[*translation-unit*](basic.link#nt:translation-unit "6.7 Program and linkage [basic.link]"),
prior to the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]") (if any),
the point after the [*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]") of the [*translation-unit*](basic.link#nt:translation-unit "6.7 Program and linkage [basic.link]") is also considered a point of instantiation,
and

- [(7.2)](#temp.point-7.2)

for any such specialization that has a point of instantiation
within the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]"),
the end of the translation unit is also
considered a point of instantiation[.](#temp.point-7.sentence-1)

A specialization for a class template has at most one point of instantiation
within a translation unit[.](#temp.point-7.sentence-2)

A specialization for any template may have points of instantiation in multiple
translation units[.](#temp.point-7.sentence-3)

If two different points of instantiation give a template specialization
different meanings according to the [one-definition rule](basic.def.odr "6.3 One-definition rule [basic.def.odr]"),
the program is ill-formed, no diagnostic required[.](#temp.point-7.sentence-4)

[8](#temp.point-8)

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

For the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of an expansion statement ([[stmt.expand]](stmt.expand "8.7 Expansion statements")),
the point of instantiation is the point of instantiation
of its enclosing templated entity, if any[.](#temp.point-8.sentence-1)

Otherwise, it immediately follows the namespace-scope declaration
or definition that contains the expansion statement[.](#temp.point-8.sentence-2)

#### [13.8.4.2](#temp.dep.candidate) Candidate functions [[temp.dep.candidate]](temp.dep.candidate)

[1](#temp.dep.candidate-1)

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

If a dependent call ([[temp.dep]](#temp.dep "13.8.3 Dependent names")) would be ill-formed or
would find a better match had the lookup for its dependent name
considered all the function declarations with external linkage
introduced in the associated namespaces in all translation units,
not just considering those declarations found in the template definition and
template instantiation contexts ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4 Argument-dependent name lookup")),
then the program is ill-formed, no diagnostic required[.](#temp.dep.candidate-1.sentence-1)

[2](#temp.dep.candidate-2)

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

[*Example [1](#temp.dep.candidate-example-1)*:

Source file "X.h":namespace Q {struct X { };}

Source file "G.h":namespace Q {void g_impl(X, X);}

Module interface unit of M1:module;#include "X.h"#include "G.h"export module M1;export template<typename T>void g(T t) { g_impl(t, Q::X{ }); // ADL in definition context finds Q​::​g_impl, g_impl not discarded}

Module interface unit of M2:module;#include "X.h"export module M2;import M1;void h(Q::X x) { g(x); // OK} â *end example*]

[3](#temp.dep.candidate-3)

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

[*Example [2](#temp.dep.candidate-example-2)*:

Module interface unit of Std:export module Std;export template<typename Iter>void indirect_swap(Iter lhs, Iter rhs){ swap(*lhs, *rhs); // swap not found by unqualified lookup, can be found only via ADL}

Module interface unit of M:export module M;import Std;

struct S { /* ...*/ };void swap(S&, S&); // #1void f(S* p, S* q){ indirect_swap(p, q); // finds #1 via ADL in instantiation context} â *end example*]

[4](#temp.dep.candidate-4)

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

[*Example [3](#temp.dep.candidate-example-3)*:

Source file "X.h":struct X { /* ... */ };
X operator+(X, X);

Module interface unit of F:export module F;export template<typename T>void f(T t) { t + t;}

Module interface unit of M:module;#include "X.h"export module M;import F;void g(X x) { f(x); // OK, instantiates f from F,// operator+ is visible in instantiation context} â *end example*]

[5](#temp.dep.candidate-5)

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

[*Example [4](#temp.dep.candidate-example-4)*:

Module interface unit of A:export module A;export template<typename T>void f(T t) { cat(t, t); // #1 dog(t, t); // #2}

Module interface unit of B:export module B;import A;export template<typename T, typename U>void g(T t, U u) { f(t);}

Source file "foo.h", not an importable header:struct foo {friend int cat(foo, foo);};int dog(foo, foo);

Module interface unit of C1:module;#include "foo.h" // dog not referenced, discardedexport module C1;import B;export template<typename T>void h(T t) { g(foo{ }, t);}

Translation unit:import C1;void i() { h(0); // error: dog not found at #2}

Importable header "bar.h":struct bar {friend int cat(bar, bar);};int dog(bar, bar);

Module interface unit of C2:module;#include "bar.h" // imports header unit "bar.h"export module C2;import B;export template<typename T>void j(T t) { g(bar{ }, t);}

Translation unit:import C2;void k() { j(0); // OK, dog found in instantiation context:// visible at end of module interface unit of C2} â *end example*]
