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.
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!
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