移动方法的替代实现(SFINAE)以分隔文件

时间:2015-08-04 16:39:23

标签: c++ templates c++11 sfinae

我有一个类,其中bool作为模板参数来控制类的行为(在我的特定情况下,它控制是否将缓存用于某些计算)。所有不受此选项影响的方法都在.h文件中定义,并在.tpp文件中实现。虽然,一个方法实现取决于传递的模板参数,我无法弄清楚如何将其实现移动到单独的文件。目前我有类似于这个例子的东西。

MyClass.h

template<bool enableCache = false>
class MyClass
{
public:
    MyClass() {}
    void someMethod();

    template<bool fwd = enableCache, typename std::enable_if<fwd>::type* = nullptr>
    unsigned int calcSomething() {
        // ask cache if calculation is necessary
        return 0;
    }

    template<bool fwd = enableCache, typename std::enable_if<!fwd>::type* = nullptr>
    unsigned int calcSomething() {
        // always recalculate
        return 1;
    }
};

#include "MyClass.tpp"

MyClass.tpp

template<enableCache>
void MyClass<enableCache>::someMethod() {
    // do something
    return;
}

此设置有效(除非我在简化原始代码时引入了一些小错误),但我也希望将calcSomething的实现移至.tpp。有人可以帮我吗?

1 个答案:

答案 0 :(得分:3)

您可以转发到非模板功能:

unsigned int calcSomething() {
    return calcSomethingImpl(std::integral_constant<bool, enableCache>{});
}

unsigned int calcSomethingImpl(std::true_type /* enableCache */) {
    // ask cache if calculation is necessary
    return 0;
}

unsigned int calcSomethingImpl(std::false_type /* enableCache */) {
    // always recalculate
    return 1;
}

这样您根本不必处理SFINAE,非模板成员函数比成员函数模板更容易推理。

此外,您可以从非模板类继承MyClass<bool >,它提供两个calcSomethingImpl受保护的函数 - 这将允许您在源文件而不是标头中定义它们(如果这是你想做的事情。)