跨库的模板函数特化符号匹配

时间:2014-06-22 23:48:57

标签: c++ linker shared-libraries template-specialization function-templates

到目前为止,我有一个设置,在标题中声明了某个功能模板getF

template <typename T> F* getF();

保持函数体未定义。然后在共享库上,getF有一些特殊化..

template<>
F* getF<int>()
{
  static int r = 42;
  static Finstance(r);
  return &Finstance;
}

template<>
F* getF<float>()
{
  static float r = 3.14159;
  static Finstance(r);
  return &Finstance;
}

上面的工作到目前为止很好,就像在客户端可执行文件中调用getF<float>()时,链接器将替换为适当的引用,如果库中没有特化,那么编译将失败并出现链接器错误(这是所需的行为)

但是,现在行为应该有一个小变化:当结果不是专用于给定的模板参数时,代码应该构建,但在运行时返回0。 所以我所做的是改变getF这样的声明:

template <typename T> F* getF() { return 0; }

问题在于,现在编译器将对所有情况使用此定义,无论库中是否存在专门化

  

问题:还有其他方法可以在运行时为函数提供一些默认行为,而无需移动   头文件的专业化?

2 个答案:

答案 0 :(得分:3)

最好的解决方案是声明库的显式特化存在。

// All in the same header file:
template <typename T> F* getF() { return 0; }
template <> F* getF<int>();
template <> F* getF<float>();

这符合标准14.7.3 / 6的规则:

  

如果一个模板,一个成员模板或一个类模板的成员被明确地专门化,那么该特化应该在第一次使用该特化之前声明,这将导致隐式实例化发生,在每个翻译单元中使用发生;无需诊断。

答案 1 :(得分:0)

基本上你需要以下内容:“当T为int或float时启用F的特殊情况”。它正是boost :: enable_if和std :: enable_if之类的构造。

启用/禁用功能与类(类更容易)之间存在细微差别。请在此处查看好的示例:boost::enable_if not in function signature

您可能需要一些MPL(Boost元编程库)来表达规则的“或”部分。