有关实例化上下文的问题



考虑 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);
}

对于f(0),评论说

foo<int,> 的实例化上下文包括

  • 翻译单元 #1 末尾的点,
  • 翻译单元 #2 末尾的点,以及
  • 调用 f(0) 的点,

我能理解第一点,因为这个规则

在模板的隐式实例化期间,其实例

化点被指定为封闭专用化([temp.point]),实例化上下文是封闭专用化的实例化上下文的并集,如果模板是在模块 M 的模块接口单元中定义的,并且实例化点不在 M 的模块接口单元中, 主模块接口单元 M 的声明序列末尾的点(在私有模块片段之前,如果有的话)。

但是,我无法弄清楚剩余的几点,尤其是第二点。如何解读这两点?

更新:

来自@Nicol波拉斯的回答

所以foo的"封闭专业化的实例化上下文"就是f的实例化上下文。其中包括 TU2 的结尾,根据您引用和强调的内容

我不认为强调的措辞说封闭专业化的实例化上下文包括"TU2 的终结"。我认为整个 [module.context#3] 应该解析为

在模板 T 的隐式实例化期间,其实例化点

被指定为封闭专用化 ([temp.point]),实例化上下文是封闭专用化的实例化上下文的并集,如果模板 T是在模块 M 的模块接口单元中定义的,并且实例化点不在 M 的模块接口单元中,M 的主模块接口单元的声明序列末尾的点(在私有模块片段之前,如果有的话)。

模板T不指定从中实例化封闭专用化的模板。

所有这些都可以追溯到你引用的内容,但没有点击链接:"封闭专业化"。从 [温度点]/1:

对于函数模板专用化、成员函数模板专用化

或类模板的成员函数或静态数据成员的专用化,如果专用化是隐式实例化的,因为它是从另一个模板专用化中引用的,并且引用它的上下文取决于模板参数,则专用化的实例化点是封闭专用化的实例化点。

在 TU2 中,函数模板foo专用于函数模板fffoo的"封闭专业化"。

所以foo的"封闭专业化的实例化上下文"就是f的实例化上下文。其中包括 TU2 的结尾,根据您引用和强调的内容。

至于第三点...这只是使用f重复的第二点。f(0)专门f,从而充当其实例化上下文的一部分。因为foo被包含在f中,这也充当foo实例化上下文的一部分。

最新更新