OSX clang++:用于 cpp 文件中显式实例化模板的体系结构x86_64的未定义符号

OSX clang++: Undefined symbols for architecture x86_64 for explicitely instantiated template in cpp file

本文关键字:体系结构 x86 符号 未定义 实例化 用于 clang++ cpp 文件 OSX      更新时间:2023-10-16

我在.h文件中定义了模板类,并在.cpp文件中定义了模板方法。此.cpp文件还包含通过template clas Class<type>显式模板实例化。

此用例在VS2019上与GCC(7.4.0(相同,可以正常工作。但是,它不适用于带有clang++的OSX(Apple LLVM版本10.0.0 clang-1000.11.45.5(。

根据文档,我相信这是一个有效的代码。有没有办法让它在 OSX 叮当声下工作?

我不想将所有实现都移动到 .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>;

我希望这也对其他人有所帮助!