如何专门化非内联模板化成员函数? (用于不同的翻译单位)

时间:2012-01-10 12:59:10

标签: c++ templates

上下文

我们开发了一个模板化的设置系统类,它将成为我们向不同体系结构的用户公开的API的一部分(更少的单词:我们不应该依赖于编译器特定的行为)

通用代码如下:

在标题

namespace Firm
{

// Class definition
class A
{
  template<class T>
  void foo(T* aParam);
};

// Non specialized template definition
template<class T>
void A::foo(T* aParam)
{
  //...
}

// Declaration of a specialization
template<>
void A::foo<int>(int* aParam); 

} // namespace

在CPP文件

namespace Firm
{

// Definition of the specialized member function
template<>
void A::foo<int>(int* aParam)
{
  //...
}

} // namespace


问题

使用gcc 4.x可以正常运行。 (即不同的编译单元在适当的时候使用专门的方法。)但是我感到不舒服,因为我读了以下条目:

Visibility of template specialization of C++ function

接受的答案状态,,如果我正确理解错误,如果模板方法的特化定义在调用中不可见站点。 (所有编译单元中的情况都不是上面列出的CPP文件但包含标题)

  1. 我无法理解为什么声明在这一点上还不够(标题提供的声明)?

  2. 如果确实是错误,是否有正确的方法来定义它的特化:

    • 非内联
    • 可用于任何包含标题的编译单元(以及与相应的.obj的链接)?

1 个答案:

答案 0 :(得分:0)

将声明放在头文件中。

编译器要么需要实例化模板(需要定义),要么需要使用c ++ 0x extern模板

看这里:https://stackoverflow.com/a/8131212/258418

修改 @单一定义规则: 你应该没问题,因为我对模板有以下行为: 在不同的o文件中创建它们(多次,由于多次编译而耗费时间),当链接器进入时它会删除重复项并使用一个实例。

另请参阅此答案/维基链接:https://stackoverflow.com/a/8133000/258418

<强> EDIT2

对于类的工作原理如下:

extern template class yourTemplate<int>; //tell the compiler to just use this like a funciton stub and do no instantiation. put this in the header

template class yourTemplate<int>; //instantiation, put this in a c file/object that you link with the project

对于你的功能它应该像这样工作:     //标题中的专业化声明     extern模板&lt;&gt;     void A :: foo(int * aParam);

//in your cpp file
template<>
void A::foo<int>(int* aParam) {
    code...
}

template class A::foo<int>(int* aParam);