[temp.dep.res]

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

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

### 13.8.4 Dependent name resolution [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*]
