正如这个答案中所解释的,模板实例化允许通过不需要为使用它们的每个新文件中的每个新类型重新编译模板来减少编译时间和大小。
我也对C++20 模块应该如何提供一个干净的解决方案来向外部项目公开模板并减少 hpp/cpp 重复感到兴奋。
允许它们一起工作的语法是什么?
例如,我希望模块看起来有点像(未经测试,因此可能是错误的代码,因为我没有足够新的编译器/不确定它是否已实现):
你好世界.cpp
export module helloworld;
import <iostream>;
template<class T>
export void hello(T t) {
std::cout << t << std::end;
}
helloworld_impl.cpp
export module helloworld_impl;
import helloworld;
// Explicit instantiation
template class hello<int>;
主文件
// How to prevent the full definition from being imported here, which would lead
// hello(1) to instantiate a new `hello<int>` instead of reusing the explicit instantiated
// one from `helloworld_impl.cpp`?
import helloworld;
int main() {
hello(1);
}
然后将在https://quuxplusone.github.io/blog/2019/11/07/modular-hello-world中提到的编译(?)
clang++ -std=c++2a -c helloworld.cpp -Xclang -emit-module-interface -o helloworld.pcm
clang++ -std=c++2a -c -fprebuilt-module-path=. -o helloworld_impl.o helloworld_impl.cpp
clang++ -std=c++2a -fprebuilt-module-path=. -o main.out main.cpp helloworld_impl.o
理想情况下,我还希望模板定义可用于外部项目。
我认为我想要的是一种导入模块的方法,并在导入时决定:
- 使用模块中的所有模板,就好像它们只是声明一样(我将在另一个文件上提供我自己的实例化)
- 使用模块中的模板,就好像它们是定义一样
这基本上是我在 C++20 之前在“从包含的标头中删除定义,但也将模板公开为外部 API”中实现的,但该设置需要复制接口两次,这似乎是模块系统基本上可以为我们做的事情。