14

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.

Mike Vine
  • 9,468
  • 25
  • 44
user119879
  • 331
  • 1
  • 7
  • 2
    More handy godbolt: https://godbolt.org/z/oooWc9n1P – Marek R May 06 '22 at 14:06
  • Also msvc gets confused: https://godbolt.org/z/x3jGG8fM4 – Marek R May 06 '22 at 14:18
  • 2
    [CWG issue 1157](https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1157) I guess? To do partial ordering of the function templates a new type should be invented for `T` in the second overload and replaced into the function parameters, but that yields an invalid type for `std::enable_if_t, T>`. – user17732522 May 06 '22 at 14:22
  • 2
    Issue 2160 under issue 1157 in the link has a more similar example. – user17732522 May 06 '22 at 14:28
  • 3
    Does this answer your question? [Template partial ordering - why does partial deduction succeed here](https://stackoverflow.com/questions/31394260/template-partial-ordering-why-does-partial-deduction-succeed-here) – n. m. could be an AI May 06 '22 at 14:41
  • The explanation in Issue 2160 and the answer in the linked question answer my question, yes. I will have to take some time to get through the details though, I guess I asked for it! – user119879 May 06 '22 at 14:55

0 Answers0