OSX clang++: 在cpp文件中,未定义x86_64架构的明确实例化模板的符号。

问题描述 投票:0回答:2

我在.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

谢谢你的帮助

c++ templates gcc clang++
2个回答
3
投票

成员函数没有被实例化。这并不奇怪,因为你做了显式实例化的工作 之前 界定 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>;

这指示编译器在使用特定的特殊化时,放弃很多隐式实例化。它将知道完整的定义在其他地方。

同时,它也起到了很好的文档作用。现在,人们只需阅读头就可以知道支持的类型。


0
投票

好吧,我回答一下我的问题。

由于我不明白的原因,clang++需要在所有其他代码之后才有这些显式实例。

所以,正确的形式是 test.cpp 文件是。

#include "test.h"

template <class T>
int CTemplateTest<T>::Test()
{
    return 42;
}

template class CTemplateTest<int>;
template class CTemplateTest<double>;

我希望这也能帮助别人!

© www.soinside.com 2019 - 2024. All rights reserved.