Why does enable_if on the function parameter type influence overload resolution?

87 Views Asked by At

See code on godbolt

#include <iostream>
#include <cmath>
#include <type_traits>

template <typename T>
void f(T, T) // 1
{
    std::cout << "Primary\n";
}

template <typename T>
void f(T, std::enable_if_t<std::is_floating_point_v<T>, T>) // 2
{
    std::cout << "Special\n";
}

/*template <typename T>
std::enable_if_t<std::is_floating_point_v<T>> f(T, T) // 3
{
    std::cout << "Special\n";
}*/

int main()
{
    f(1.1, 1.1); // prints 'Primary'
    return 0;
}

In the above code, std::enable_if is applied to the function type of the second function template overload. The function is called with [T = double] deduced, and it calls overload 1. However, if I comment out overload 2 and replace it with overload 3, then the compiler will complain that the call is ambiguous. I expected that in the first case too, why does the compiler prefer overload 1 over 2?

I read the section on 'function template overloading', but to me it looks like overload 2 is more specialized.

0

There are 0 best solutions below