Using std::enable_if

c++, c++11, enable-if, templates

Solution

I'd make several changes to your code, beginning with the unconstrained function template. Since you're handling arithmetic types separately, that should only be selected if `T` is neither integral nor floating point.

template <typename T>
typename std::enable_if<!std::is_integral<T>::value &&
                        !std::is_floating_point<T>::value, bool>::type 
    Equal(const std::string& s, const T& data)
{return s == data;}

Now, the way you've defined `Equal` for integral and floating point types causes the `T` to be a non-deduced context. So move the `enable_if` to a dummy template parameter to allow deduction (you could also use the return type, as above).

template <typename T,
          typename std::enable_if<std::is_integral<T>::value, T>::type* = nullptr>
bool Equal(const std::string& s, const T& data)
{
    //int specific
    return false;
}

template <typename T,
          typename std::enable_if<std::is_floating_point<T>::value, T>::type* = nullptr>
bool Equal(const std::string& s, const T& data)
{
    //Float specific
    return false;
}

Finally, there's no need to specialize for handling `Ip`, create an overload instead.

//Overload
bool Equal(const std::string& s, const Ip& data)
{
   //Ip specific
    return false;
}

Live demo

Problem

I'm trying to specialize a function for a range of types using `std::enable_if`. Here is a a simpler version of what I'm trying to accomplish. ``` #include <type_traits> #include <string> struct Ip {}; template <typename T> bool Equal(const std::string& s, const T& data) {return s == data;} template <typename T> bool Equal(const std::string& s, const typename std::enable_if<std::is_integral<T>::value, T>::type& data) { //int specific } template <typename T> bool Equal(const std::string& s, const typename std::enable_if<std::is_floating_point<T>::value, T>::type& data) { //Float specific } //Specialization template <> bool Equal(const std::string& s, const Ip& data) { //Ip specific } int main() { //Equal("21",21); // Do not compile Equal("21","42.5"); // Compile } ``` but when trying to compile, the template functions with `std::enable_if` does not seem to participate in the resolution, and so the compiler tells me that there is no function that match my function call. I tried using `std::enable_if` with the return type, but no luck there either. I'm sure there is something I'm doing terribly wrong in this code, or maybe I'm trying to do this the wrong way. I'm trying to not write every int specialization (int, short, long, long long, ...), so does anyone have a solution for this ?

Original source