Specialize template based on positivity of argument

Go To StackoverFlow.com

5

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.

2012-04-04 19:09
by Malabarba


13

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!

2012-04-04 19:13
by templatetypedef
Matter of style, but I prefer to put the enable_if on the return type so there isn't a magic parameter hanging around confusing things (users and the function's type) - GManNickG 2012-04-04 19:33
Ads