我在.h文件中定义了模板类,在.cpp文件中定义了模板方法。这个.cpp文件也包含了明确的模板实例化,它通过 template clas Class<type>
.
这个用例在VS2019上可以正常工作,和在GCC(7.4.0)上一样。但是,在OSX上用clang++(Apple LLVM版本10.0.0 clang-1000.11.45.5)却不能工作。
根据文档,我相信这是一个有效的代码。有什么方法可以让它在OSX clang下工作吗?
我不想把所有的实现都移到.h中,因为更好的可读性,也因为我只需要两个三个模板实例。
这是我的测试文件。
test.h
#pragma once
template <class T>
class CTemplateTest
{
public:
int Test();
};
test.cpp
#include "test.h"
template class CTemplateTest<int>;
template class CTemplateTest<double>;
template <class T>
int CTemplateTest<T>::Test()
{
return 42;
}
main.cpp
#include "test.h"
int main(int argc, char** argv)
{
CTemplateTest<int> t1;
CTemplateTest<double> t2;
t1.Test();
t2.Test();
}
output
Undefined symbols for architecture x86_64:
"CTemplateTest<double>::Test()", referenced from:
_main in main.o
"CTemplateTest<int>::Test()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
谢谢你的帮助
成员函数没有被实例化。这并不奇怪,因为你做了显式实例化的工作 之前 界定 CTemplateTest<T>::Test
. 将显式实例化移入到了 test.cpp
template <class T>
int CTemplateTest<T>::Test()
{
return 42;
}
template class CTemplateTest<int>;
template class CTemplateTest<double>;
我建议你在头中添加一个明确的实例化声明。
template <class T>
class CTemplateTest
{
public:
int Test();
};
extern template class CTemplateTest<int>;
extern template class CTemplateTest<double>;
这指示编译器在使用特定的特殊化时,放弃很多隐式实例化。它将知道完整的定义在其他地方。
同时,它也起到了很好的文档作用。现在,人们只需阅读头就可以知道支持的类型。
好吧,我回答一下我的问题。
由于我不明白的原因,clang++需要在所有其他代码之后才有这些显式实例。
所以,正确的形式是 test.cpp
文件是。
#include "test.h"
template <class T>
int CTemplateTest<T>::Test()
{
return 42;
}
template class CTemplateTest<int>;
template class CTemplateTest<double>;
我希望这也能帮助别人!