Search code examples
c++templatesc++17enable-ifnon-type

Template parameters SFINAE not using a template argument


Why is such a construct disallowed in C++:

#include <type_traits>

template<std::enable_if_t<true, bool> = true>
void fn() {}

template<std::enable_if_t<false, bool> = true>
void fn() {}

int main()
{
    fn();
    return 0;
}

It seems like the compiler is complaining about the fact that enable_if is missing its template argument I believe? Is there a way to achieve the behaviour above without introducing another template parameter set to some default value for example?


Solution

  • There needs to be a template parameter to substitute in order for SFINAE to take place. So create a dummy template parameter and a dummy trait that will take it and returns true and false respectively.

    template<class T>
    constexpr bool always_true = true;
    template<class T>
    constexpr bool always_false = false;
    
    template<class T=void, std::enable_if_t<always_true<T>>* = nullptr>
    void fn() {}
    
    template<class T=void, std::enable_if_t<always_false<T>>* = nullptr>
    void fn() {}