Specialize template based on positivity of argument

c++, math, templates

Solution

One option would be to use another level of indirection. Define an auxiliary template that takes in two arguments - the number `n` and a `bool` representing whether or not `n` is negative, then specialize that template for when `n` is negative. Then, have your `f` function instantiate the template with the right arguments.

For example:

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();
}

Another option is to use SFINAE overloading and the `std::enable_if` template class from C++11 (or Boost's equivalent);

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 ... */
}

Each of these functions will only be available for overload resolution if `n` has the proper sign, so the correct version will always be called.

Hope this helps!

Problem

Given a template ``` template <int n> void f(){...}; ``` I know I can specialize it for specific values of `n` by doing: ``` template <> void f<2>(){...}; ``` But, is there a method which allows me to specialize it for all positive `n`? I thought of doing the following ``` template <int n> void f<n>(){ int dummy[n]; //invalid for n < 0 ... }; ``` So for `n<0` this code is invalid and the compiler would resort to the previous definition. Unfortunately, all I get is a `redefinition of 'void f<n>()'` error. Note: I'm guessing this is probably not supported by the standard. I'm asking if there isn't some method (maybe some template metaprogramming) to achieve this effect.

Original source