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
foo
is 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