Shall more type constrained function be preferred to resolve overload ambiguity in C++?

Viewed 69

Please consider a C++20 code example with an overloaded function foo:

#include <concepts>

template<typename T> int foo(T) { return 0; }
template<typename T> int foo(T&) requires std::same_as<T, const T> { return 1; }

int main() { const int x = 1; return foo(x); }

I would expect that the variant foo(T&) requires... be preferred automatically as more constrained over more general variant foo(T). And indeed Clang and MSVC prefer it.

But GCC keeps complaining on the ambiguity https://gcc.godbolt.org/z/hz9rrbPca :

error: call of overloaded 'foo(const int&)' is ambiguous
    6 | int main() { const int x = 1; return foo(x); }
      |                                      ~~~^~~
<source>:3:26: note: candidate: 'int foo(T) [with T = int]'
    3 | template<typename T> int foo(T) { return 0; }
      |                          ^~~
<source>:4:26: note: candidate: 'int foo(T&) requires  same_as<T, const T> [with T = const int]'
    4 | template<typename T> int foo(T&) requires std::same_as<T, const T> { return 1; }
      |                          ^~~

Please help to clarify, which of the compilers is more correct here?

0 Answers
Related