图 1: 功能模板
模板头文件.h
template<typename T>
void f();
模板Cpp.cpp
template<typename T>
void f(){
//...
}
//explicit instantation
template void f<T>();
主文件
#include "TemplHeader.h"
extern template void f<T>(); //is this correct?
int main() {
f<char>();
return 0;
}
这是使用 extern template
的正确方法,还是我只将此关键字用于类模板,如图 2 所示?
图 2: 类模板
模板头文件.h
template<typename T>
class foo {
T f();
};
模板Cpp.cpp
template<typename T>
void foo<T>::f() {
//...
}
//explicit instantation
template class foo<int>;
主文件
#include "TemplHeader.h"
extern template class foo<int>();
int main() {
foo<int> test;
return 0;
}
我知道将所有这些放在一个头文件中很好,但是如果我们在多个文件中实例化具有相同参数的模板,那么我们会得到多个相同的定义,编译器会将它们全部删除(除了一个)以避免错误。如何使用 extern template
?我们可以只将它用于类,还是也可以将它用于函数?
此外,图 1 和图 2 可以扩展为模板位于单个头文件中的解决方案。在这种情况下,我们需要使用 extern template
关键字来避免多个相同的实例。这也仅适用于类或函数吗?
原文由 codekiddy 发布,翻译遵循 CC BY-SA 4.0 许可协议
您应该只使用
extern template
强制编译器在 您知道 模板将在其他地方实例化时 不 实例化模板。它用于减少编译时间和目标文件大小。例如:
这将产生以下目标文件:
如果两个文件链接在一起,一个
void ReallyBigFunction<int>()
将被丢弃,导致编译时间和目标文件大小的浪费。为了不浪费编译时间和目标文件大小,有一个
extern
关键字使编译器不编译模板函数。 当且仅当您知道 它在其他地方的同一个二进制文件中使用时,您才应该使用它。将
source2.cpp
更改为:将产生以下目标文件:
当这两个链接在一起时,第二个目标文件将只使用第一个目标文件中的符号。无需丢弃,也不会浪费编译时间和目标文件大小。
这应该只在项目中使用,例如当您多次使用
vector<int>
类的模板时,您应该在除一个源文件之外的所有文件中使用extern
。这也适用于类和函数合一,甚至模板成员函数。