des*_*sio 7 c++ templates c++20 c++-modules
我正在创建一个库,并且 C++20 模块内有一个类模板,我想添加一个实例化,以减少使用我的库的每个项目的编译时间。
这些不同的实现是否等效,或者是否有更好的方法来实现?
1)
//mod.cpp
export module mod;
export template<typename T>
struct mystruct{ T i;};
export template class mystruct<int>;
Run Code Online (Sandbox Code Playgroud)
//mod.cpp
export module mod;
export template<typename T>
struct mystruct{ T i;};
template class mystruct<int>;
Run Code Online (Sandbox Code Playgroud)
//mod.cpp
export module mod;
export template<typename T>
struct mystruct{ T i;};
export extern template class mystruct<int>;
//mod_impl.cpp
module mod;
template class mystruct<int>;
Run Code Online (Sandbox Code Playgroud)
编辑:这个答案只说 2. 有效,但我的观点是 1. 和 3. 是否也等于 2.
模块影响两件事:名称的范围和声明的可达性。仅当它们位于模块的权限范围内时(即:在导入的模块接口 TU 中并且不在全局模块片段中),这两者才重要。
\n在模块权限内声明的名称仅当由该export模块编辑时才能在该模块外部使用。在显式模板实例化的情况下,模板本身已经导出,因此模块外部的用户已经可以使用该名称。
然而,显式模板实例化定义也是一种声明。模块控制声明的可达性。问题是,声明的可达性规则实际上并不关心export实际上
\n\n如果对于实例化上下文([module.context])中的任何点 P,声明 D 是可达的,
\n\n
\n- 在同一翻译单元中,D 出现在 P 之前,或者
\n- D 不会被丢弃([module.global.frag]),出现在可从 P 到达的翻译单元中,并且不会出现在私有模块片段中。
\n[注:报关是否出口无关与是否可达无关\xe2\x80\x94 尾注]
\n
添加了强调。
\n这些规则只关心哪些 TU 已被导入(以及声明是否在全局/私有模块片段中)。
\n因此,如果主模板声明已export编辑,则导入模块文件之一中的显式模板实例化(不在全局/私有模块片段中)可由导入它的任何代码访问。
export因此,是否显式模板实例化并不重要。如果主模板已被export编辑,则其名称可能已被使用,因此唯一重要的是显式模板实例化是否可见。
所以你的 #1 和 2 在功能上是等效的。最好不要做export一些你不需要的事情。
至于 的行为extern template,这很有趣。
虽然extern规范化表示外部链接,但这不适用于extern template. 所以我们不存在链接问题。由于extern template模块的导入者可以访问该声明(如前所述),因此他们会看到它并尊重它。
所以唯一的问题是“mod_impl.cpp”中的显式定义是否也是可达的。但这不是一个问题,因为只有定义的声明部分是“可访问的”。也就是说,可达性仅对声明重要。
\n显式实例化定义位于不同的 TU 中。因此,它只会在该 TU 中实例化;导入模块的代码仅到达声明。因此,它不会实例化模板。
\n所以,是的,你可以进行extern template体操(不过,export这并不重要)。但这与将显式实例化放入模块接口中没有什么不同,而且这样做更干净。
| 归档时间: |
|
| 查看次数: |
2688 次 |
| 最近记录: |