总结
这个问题是关于在几个不同的翻译单元中实现单个模板类实例化的单独编译。
问题
对于非模板类,可以将定义放在多个 .cpp 文件中并分别编译。例如:
档案啊:
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-头文件错误。