Search code examples
c++templatessfinaeenable-if

Unwanted substitution of bool overload when trying to use sfinae overload


The answer to this question exists exactly almost, but I could not find it.

The code below as expected does not work due to the implicit conversion of integer type to bool.

template <typename T, typename std::enable_if<std::is_integral<T>::value &&
                                              std::is_signed<T>::value &&
                                              !std::is_same<T, bool>::value, T>::type>
inline void test(T) { std::cout << "int" << std::endl; }

inline void test(bool) { std::cout << "bool" << std::endl; }

int main()
{
    test(int());
    test(bool());
}

To fix this I've tried :

  • priority tagging
  • converting bool overload to specialization
  • std::enable_if<std::is_same<T, bool>::value, T>::type> on bool overload

but all with no effect(either compilation error, or two bool calls).

Is there any way to separate this two overloads?


Solution

  • The problem is, for the 1st overload, the 2nd template parameter, which is declared as a non-type parameter, can't be deduced and makes the 1st overload can't be selected at all.

    You can specify a default value for the 2nd template parameter. e.g.

    template <typename T, typename std::enable_if<std::is_integral<T>::value &&
                                                  std::is_signed<T>::value &&
                                                  !std::is_same<T, bool>::value, T>::type = 0>
    //                                                                                    ^^^
    inline void test(T) { std::cout << "int" << std::endl; }
    

    LIVE