[module.context]

# 10 Modules [[module]](./#module)

## 10.6 Instantiation context [module.context]

[1](#1)

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

The [*instantiation context*](#def:instantiation_context "10.6 Instantiation context [module.context]") is a set of points within the program
that determines which declarations are found by
argument-dependent name lookup ([[basic.lookup.argdep]](basic.lookup.argdep "6.5.4 Argument-dependent name lookup"))
and which are reachable ([[module.reach]](module.reach "10.7 Reachability"))
in the context of a particular declaration or template instantiation[.](#1.sentence-1)

[2](#2)

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

During the implicit definition of
a defaulted function ([[special]](special "11.4.4 Special member functions"), [[class.compare.default]](class.compare.default "11.10.1 Defaulted comparison operator functions")),
the instantiation context contains each point in
the instantiation context from the definition of the class and
each point in
the instantiation context of the program construct that
resulted in the implicit definition of the defaulted function[.](#2.sentence-1)

[3](#3)

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

During the implicit instantiation of a template
whose point of instantiation is specified as
that of an enclosing specialization ([[temp.point]](temp.point "13.8.4.1 Point of instantiation")),
the instantiation context contains each point in
the instantiation context of the enclosing specialization and,
if the template is defined in a module interface unit of a module M and the point of instantiation is not in a module interface unit of M,
the point at the end of the[*declaration-seq*](dcl.pre#nt:declaration-seq "9.1 Preamble [dcl.pre]") of the
primary module interface unit of M (prior to the [*private-module-fragment*](module.private.frag#nt:private-module-fragment "10.5 Private module fragment [module.private.frag]"), if any)[.](#3.sentence-1)

[4](#4)

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

During the implicit instantiation of a template
that is implicitly instantiated because it is referenced
from within the implicit definition of a defaulted function,
the instantiation context contains each point in the instantiation context of
the defaulted function[.](#4.sentence-1)

[5](#5)

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

During the instantiation of any other template specialization,
the instantiation context contains the point of instantiation
of the template[.](#5.sentence-1)

[6](#6)

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

During the implicit instantiation of any construct
that resulted from the evaluation of an expression
as a core constant expression,
the instantiation context contains
each point in the evaluation context ([[expr.const]](expr.const "7.7 Constant expressions"))[.](#6.sentence-1)

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

Implicit instantiations can result
from invocations of library functions ([[meta.reflection]](meta.reflection "21.4 Reflection"))[.](#6.sentence-2)

The evaluation context can include synthesized points
associated with injected declarations
produced by std​::​meta​::​define_aggregate ([[meta.reflection.define.aggregate]](meta.reflection.define.aggregate "21.4.16 Reflection class definition generation"))[.](#6.sentence-3)

â *end note*]

[7](#7)

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

In any other case, the instantiation context
at a point within the program
contains that point[.](#7.sentence-1)

[8](#8)

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

The instantiation context contains only the points specified above[.](#8.sentence-1)

[9](#9)

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

[*Example [1](#example-1)*:

Translation unit #1:export module stuff;export template<typename T, typename U> void foo(T, U u) { auto v = u; }export template<typename T, typename U> void bar(T, U u) { auto v = *u; }

Translation unit #2:export module M1;import "defn.h"; // provides struct X {};import stuff;export template<typename T> void f(T t) { X x;
 foo(t, x);}

Translation unit #3:export module M2;import "decl.h"; // provides struct X; (not a definition)import stuff;export template<typename T> void g(T t) { X *x;
 bar(t, x);}

Translation unit #4:import M1;import M2;void test() { f(0);
 g(0);} 

The call to f(0) is valid;
the instantiation context of foo<int, X> comprises

- [(9.1)](#9.1)

the point at the end of translation unit #1,

- [(9.2)](#9.2)

the point at the end of translation unit #2, and

- [(9.3)](#9.3)

the point of the call to f(0),

so the definition of X is reachable ([[module.reach]](module.reach "10.7 Reachability"))[.](#9.sentence-1)

It is unspecified whether the call to g(0) is valid:
the instantiation context of bar<int, X> comprises

- [(9.4)](#9.4)

the point at the end of translation unit #1,

- [(9.5)](#9.5)

the point at the end of translation unit #3, and

- [(9.6)](#9.6)

the point of the call to g(0),

so the definition of X need not be reachable,
as described in [[module.reach]](module.reach "10.7 Reachability")[.](#9.sentence-2)

â *end example*]
