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>;

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