基于参数的积极性专门化模板

时间:2012-04-04 19:09:09

标签: c++ templates math

给出模板

template <int n>
void f(){...};

我知道我可以通过以下方式将其专门用于n的特定值:

template <>
void f<2>(){...};

但是,有没有一种方法可以让我为所有积极的n专门化它?

我想做以下

template <int n>
void f<n>(){
    int dummy[n]; //invalid for n < 0
    ...
};

因此,对于n<0,此代码无效,编译器将采用先前的定义。不幸的是,我得到的只是redefinition of 'void f<n>()'错误。

注意:我猜这个标准可能不支持。我问是否有一些方法(可能是一些模板元编程)来实现这种效果。

1 个答案:

答案 0 :(得分:13)

一种选择是使用另一级别的间接。定义一个辅助模板,它接受两个参数 - 数字nbool表示n是否为负数,然后在n为负数时专门化该模板。然后,让您的f函数使用正确的参数实例化模板。

例如:

template <int n, bool isNegative> struct fImpl {
    static void f() {
       /* ... code for when n is positive ... */
    }
};
template <int n> struct fImpl<n, true> {
    static void f() {
       /* ... code for when n is negative ... */
    }
};

template <int n> void f() {
    fImpl<n, (n < 0)>::f();
}

另一个选择是使用SFINAE overloading和来自C ++ 11的std::enable_if模板类(或Boost的等价物);

template <int n> void f(typename std::enable_if<(n < 0)>::type* = 0) {
    /* ... n is negative ... */
}

template <int n> void f(typename std::enable_if<(n >= 0)>::type* = 0) {
    /* ... n is positive ... */
}

如果n具有正确的符号,则每个功能仅可用于重载解析,因此将始终调用正确的版本。

希望这有帮助!