【发布时间】:2014-02-03 18:07:47
【问题描述】:
总结
这个问题是关于在几个不同的翻译单元中实现单个模板类实例化的单独编译。
问题
对于非模板类,可以将定义放在几个 .cpp 文件中并分别编译它们。例如:
文件 A.h:
class A {
public:
void func1();
void func2();
void func3() { /* defined in class declaration */}
}
文件 A1.cpp:
void A::func1() { /* do smth */ }
文件 A2.cpp:
void A::func2() { /* do smth else */ }
现在我尝试对模板类做类似的事情。因为我确切地知道我需要哪些实例,所以我明确地实例化了模板。我正在分别编译每个实例化,因为成员函数包含相当大的数学表达式,这可能会在高优化级别上大大降低编译器的速度。所以我尝试了以下方法:
文件 TA.h:
template <typename T>
class TA {
public:
void func1();
void func2();
void func3() { /* defined in class declaration */}
}
文件 TA1.cpp:
template <typename T>
void TA<T>::func1() { /* do smth */ }
template class TA<sometype>;
文件 TA2.cpp:
template <typename T>
void TA<T>::func2() { /* do smth else */ }
template class TA<sometype>;
它适用于 Linux 上的 clang 和 GCC,但在重复符号错误期间链接期间在 Mac 上使用 GCC 失败(在此示例中,由于 func3,它在 TA1.cpp 和 TA2.cpp 中都已实例化)。
然后我在标准中偶然发现了这句话:
C++11.14.7,第 5 段:
对于给定的模板和给定的一组模板参数,
-- 显式实例化定义在程序中最多出现一次,
-- ...
这是否意味着即使使用显式实例化也不可能(不允许)单独编译模板类(隐式实例化显然不可能)?
PS 我不在乎,因为我已经得到了我的答案,但是任何认为这里有答案的人 https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file 是错误的。
【问题讨论】:
-
隐式实例化显然是必要的。
-
@LightnessRacesinOrbit 隐式实例化需要如何单独编译?
-
@Vayun:隐式模板实例化在使用时发生。当您在两个或多个 TU 中使用模板时,编译器已经为每个 TU 实例化了模板。编译器不可能知道其他一些 TU 已经实例化了它。因此,它必须是合法的。
标签: c++ templates explicit-instantiation