c++ - 链接模板目标文件 - clang 和 gcc 的不同行为

标签 c++ templates gcc linker clang

关于 gcc 和 clang 之间的不同行为有很多问题。但是我还没有找到解决问题的方法。

我使用模板,我想传播类的定义和实现。我读过(很多)我知道不同的可能性。我选择特定的声明,我想支持哪些模板。与:

   template class Temp<char>;
   template class Temp<double>;

如果我将这些行放在 template.cc 文件的末尾,我会选择我支持的模板,这些模板实际上有效。但是使用 gcc 我也可以将它写在头文件中。 Clang 不支持它,我收到链接错误。

但是为什么?头文件中使用模板的声明有什么问题???

这是我的玩具示例:

模板.hh

#pragma once
#include <iostream>

template<typename T>
class Temp
{
public:
    Temp(T data);
    virtual ~Temp (){};
    void print();

private:
    T data_;
};

//Only gcc can support this
//template class Temp<char>;
//template class Temp<double> 

模板.cc

#include "template.hh"                                                                                           

template<typename T>
Temp<T>::Temp(T data): data_(data)
{
}

template<typename T>
void Temp<T>::print()
{
    std::cout << data_ << " " << sizeof(data_) << std::endl;
}

//Delete those, if it is used in header
template class Temp<char>;
template class Temp<double>;

测试.cc

#include "template.hh"

int main(int argc, char *argv[])
{
    Temp<char> temp = Temp<char>('c');
    temp.print();

    Temp<double> temp2 = Temp<double>(1.0);
    temp2.print();
    return 0;
}

期望的输出:

c  1
1  8

最佳答案

显式模板实例化属于“.cc”实现文件,而不是 header 。如果你想在 header 中声明它,你可以使用 extern 来实现:

extern template class Temp<char>;
extern template class Temp<double>;

这将避免您在使用 Clang 时可能遇到的多重定义符号。

可能是GCC在头文件中支持显式实例化,但这并不意味着它是正确的C++,只是GCC在这种情况下是自由的。不要依赖它。

关于c++ - 链接模板目标文件 - clang 和 gcc 的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34284190/

相关文章:

c - 如何删除 HINSTANCE 到 int 的错误转换?

c++ - C++ 头文件中的声明和初始化过多

c++ - 当观察者希望观察不同的项目时实现观察者模式

c++ - "Class"从模板类派生时没有命名类型

c++ - fatal error C1001 : internal error trying to use templates

c++ - 非静态数据成员初始化程序中 lambda 函数的段错误

c++ - #define 导致 "expected primary-expression"错误

c++ - streambuf 获取 streampos

c++ - QVariant.toXXX 函数的函数指针

c - GCC 4.6.3 Linux -O3 启用优化列表与应用于代码差异。优化顺序是否影响代码编译?