OSX clang++:体系结构的未定义符号 x86_64 在 cpp 文件中显式实例化的模板
OSX clang++: Undefined symbols for architecture x86_64 for explicitely instantiated template in cpp file
我在 .h 文件中定义了模板 class,并且在 .cpp 文件中定义了模板方法。此 .cpp 文件还包含通过 template clas Class<type>
.
显式模板实例化
此用例在 VS2019 上与在 GCC (7.4.0) 上一样正常工作。但是,它不适用于 OSX with clang++(Apple LLVM 版本 10.0.0 clang-1000.11.45.5)。
根据文档,我认为这是一个有效的代码。有什么方法可以让它在 OSX clang 下工作吗?
我不想将所有实现都移动到 .h,因为这样可读性更好,而且我只需要 two/three 模板实例化。
这是我的测试文件:
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>;
并且我建议您在 header
中添加显式实例化声明
template <class T>
class CTemplateTest
{
public:
int Test();
};
extern template class CTemplateTest<int>;
extern template class CTemplateTest<double>;
这指示编译器在使用特定特化时放弃大部分隐式实例化。它会知道完整的定义在别处。
此外,它还有一个很好的文档用途。现在只要阅读 header.
就可以知道支持的类型
好的,我会回答我的问题。
由于我不明白 clang++ 需要在所有其他代码之后进行这些显式实例化的原因。
因此,test.cpp
文件的正确格式是:
#include "test.h"
template <class T>
int CTemplateTest<T>::Test()
{
return 42;
}
template class CTemplateTest<int>;
template class CTemplateTest<double>;
我希望这对其他人也有帮助!
我在 .h 文件中定义了模板 class,并且在 .cpp 文件中定义了模板方法。此 .cpp 文件还包含通过 template clas Class<type>
.
此用例在 VS2019 上与在 GCC (7.4.0) 上一样正常工作。但是,它不适用于 OSX with clang++(Apple LLVM 版本 10.0.0 clang-1000.11.45.5)。
根据文档,我认为这是一个有效的代码。有什么方法可以让它在 OSX clang 下工作吗?
我不想将所有实现都移动到 .h,因为这样可读性更好,而且我只需要 two/three 模板实例化。
这是我的测试文件:
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>;
并且我建议您在 header
中添加显式实例化声明template <class T>
class CTemplateTest
{
public:
int Test();
};
extern template class CTemplateTest<int>;
extern template class CTemplateTest<double>;
这指示编译器在使用特定特化时放弃大部分隐式实例化。它会知道完整的定义在别处。
此外,它还有一个很好的文档用途。现在只要阅读 header.
就可以知道支持的类型好的,我会回答我的问题。
由于我不明白 clang++ 需要在所有其他代码之后进行这些显式实例化的原因。
因此,test.cpp
文件的正确格式是:
#include "test.h"
template <class T>
int CTemplateTest<T>::Test()
{
return 42;
}
template class CTemplateTest<int>;
template class CTemplateTest<double>;
我希望这对其他人也有帮助!