到目前为止,我有一个设置,在标题中声明了某个功能模板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; }
问题在于,现在编译器将对所有情况使用此定义,无论库中是否存在专门化
问题:还有其他方法可以在运行时为函数提供一些默认行为,而无需移动 头文件的专业化?
答案 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元编程库)来表达规则的“或”部分。