mkmostafa mkmostafa - 11 months ago 50
C++ Question

how to use enable_if with overloads

enum class enabler{};

template<typename T>
class X {
template<typename std::enable_if<std::is_class<T>::value,enabler>::type = enabler()>
void func();
void func(int a);
void func(std::string b);

I have this class with these 3 overloads for
. I need the second/third versions to be available for both class/non-class types, and the first version to be available only for class types. when I tried to use
as above, the class instantiation for non-class types gives compile error.


For SFINAE to work, the template argument must be deduced. In your case, T is already known by the time you attempt to instantiate func, so if the enable_if condition is false, instead of SFINAE, you get a hard error.

To fix the error, just add a template parameter whose default value is T, and use this new parameter in the enable_if check. Now deduction occurs and SFINAE can kick in for non-class types.

template<typename U = T,
         typename std::enable_if<std::is_class<U>::value,enabler>::type = enabler()>
void func();

And you don't really need a dedicated enabler type either, this works too

template<typename U = T,
         typename std::enable_if<std::is_class<U>::value, int>::type* = nullptr>
void func();