This is definitely a trivial question, but I couldn't figure out how to do this.
I have a template function, say template <unsigned int N> void my_function()
. Now, I have two different implementations for my_function
, the first should be used if N
is bigger than, say, 100, the other if N
is smaller than that.
I tried to use SFINAE like this:
template <unsigned int N, typename = enable_if <N >= 100> :: type> my_function()
{
// First implementation
}
template <unsigned int N, typename = enable_if <N < 100> :: type> my_function()
{
// Second implementation
}
But that's declaring the same function two times. Then I tried doing something like
template <unsigned int N, bool = (N >= 100)> my_function();
And then implementing the two functions with the two different values of the boolean. No success, since it is a partial specialization.
Then I tried to wrap N
as a struct parameter, and the bool in the function call, but it is specializing a member function before specializing the class, which cannot be done.
Is there a reasonable way to do this?
Try this instead:
#include <type_traits>
#include <iostream>
template <unsigned int N, typename std::enable_if <N >= 100> :: type* = nullptr>
void my_function()
{
std::cout << "N >= 100" << std::endl;
}
template <unsigned int N, typename std::enable_if <N < 100> :: type* = nullptr>
void my_function()
{
std::cout << "N < 100" << std::endl;
}
int main()
{
my_function<42>();
my_function<100>();
}
Template default parameters do not participate in the overload (and hence SFINAE does not apply). On the other hand, in the snippet above, the dependent template non-type parameter is on the left hand side of the assignment, so SFINAE kicks in.
If you don't like enable_if for some reason, you can always go for tag dispatch:
#include <type_traits>
class low {};
class high {};
template <int N, class T>
void func(T, low)
{
// version for high N
}
template <int N, class T>
void func(T, high)
{
// version for low N
}
template <int N, class T>
void func(T val)
{
func<N>(val, std::conditional_t<(N>=100), high, low>{});
}
int main()
{
func<3>(3.14159); // low version
func<256>("Yo"); // high version
}
In this case, we could restrict the tags to simple things like true_type and false_type, but in general this might be an alternative approach.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With