[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 void foo(T, U u) { auto v = u; }export template void bar(T, U u) { auto v = *u; } Translation unit #2:export module M1;import "defn.h"; // provides struct X {};import stuff;export template 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 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 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 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*]