Consider the following example in module.context p7
//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);
}
For f(0), the comment says that
the instantiation context of foo<int, X> comprises
- the point at the end of translation unit #1,
- the point at the end of translation unit #2, and
- the point of the call to f(0),
I can understand the first point, because of this rule
During the implicit instantiation of a template whose point of instantiation is specified as that of an enclosing specialization ([temp.point]), the instantiation context is the union of 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 of the primary module interface unit of M (prior to the private-module-fragment, if any).
However, I cannot figure out the remaining points, especially the second one. How to interpret such two points?
From the answers of @Nicol Bolas
So "the instantiation context of the enclosing specialization" of
foois the instantiation context off. Which includes the end of TU2, pursuant to what you quoted and emphasized.
I don't think the emphasized wording says the instantiation context of the enclosing specialization comprises "the end of TU2". I think the whole [module.context#3] should be parsed as that
During the implicit instantiation of a template T whose point of instantiation is specified as that of an enclosing specialization ([temp.point]), the instantiation context is the union of the instantiation context of the enclosing specialization and, if the template T 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 of the primary module interface unit of M (prior to the private-module-fragment, if any).
The template T does not designate the template from which the enclosing specialization is instantiated.
All of this goes back to what you quoted but didn't follow the link on: "enclosing specialization". From [temp.point]/1:
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.
In TU2, the function template foo is specialized within the function template f. f is the "enclosing specialization" of foo.
So "the instantiation context of the enclosing specialization" of foo is the instantiation context of f. Which includes the end of TU2, pursuant to what you quoted and emphasized.
As for the third point... it's just the second point repeated for the use of f. f(0) specializes f, thereby acting as part of its instantiation context. Because foo is enclosed within f, this also acts as part of the instantiation context for foo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With