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

Mal*_*rba 5 c++ math templates

给出一个模板

template <int n>
void f(){...};
Run Code Online (Sandbox Code Playgroud)

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

template <>
void f<2>(){...};
Run Code Online (Sandbox Code Playgroud)

但是,有没有一种方法可以让我专注于所有积极的方法n

我想到了以下几点

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

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

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

tem*_*def 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();
}
Run Code Online (Sandbox Code Playgroud)

另一个选择是使用SFINAE重载std::enable_ifC++ 11中的模板类(或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 ... */
}
Run Code Online (Sandbox Code Playgroud)

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

希望这可以帮助!

  • 风格很重要,但我更喜欢把`enable_if`放在返回类型上,这样就没有一个神奇的参数可以解决混乱的事情(用户和函数的类型). (5认同)