小编Tri*_*her的帖子

标头中没有声明的模板类成员特化

我有一个模板类,我在一个标题中声明了一个方法,并且标题中没有该方法的定义.在.cc文件中,我定义了该方法的特化,而没有在标题中声明它们.在另一个.cc文件中,我为不同的模板参数调用该方法,其中存在特化.它看起来像这样:

foo.h中:

template<typename T>
class Foo {
public:
  static int bar();
};
Run Code Online (Sandbox Code Playgroud)

foo.cc:

#include "foo.h"

template<>
int Foo<int>::bar() {
  return 1;
}

template<>
int Foo<double>::bar() {
  return 2;
}
Run Code Online (Sandbox Code Playgroud)

main.cc:

#include <iostream>
#include "foo.h"

int main(int argc, char **argv) {
  std::cout << Foo<int>::bar() << std::endl;
  std::cout << Foo<double>::bar() << std::endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

对于所有C++标准(c ++ 98,gnu ++ 98,c ++ 11和gnu ++ 11),该程序与gcc 4.7.2成功编译和链接.输出是:

1
2
Run Code Online (Sandbox Code Playgroud)

这对我来说很有意义.因为main.cc转换单元没有看到它的定义bar()或任何特化,所以它期望调用在一些其他转换单元bar()中使用非bar()特定定义的显式实例化.但由于名称修改是可预测的,因此foo.cc中的特殊化具有与非专用定义的显式实例化相同的符号名称,因此main.cc能够使用这些特化而不会在该转换单元中声明它们.

我的问题是:这是一个意外,还是C++标准规定的这种行为?换句话说,这个代码是否可移植?

我能找到的最相关的先前问题是模板类成员专业化的声明,但它不包括这个特定情况.

(如果您想知道为什么这对我来说很重要,那是因为我使用这样的代码作为一种编译时查找表,如果我不声明特化,它会更短.)

c++ templates declaration template-specialization

12
推荐指数
1
解决办法
1779
查看次数