Следует ли предпочесть больше функций с ограничениями типа для устранения неоднозначности перегрузки в C++?
Пожалуйста, рассмотрите пример кода C++20 с перегруженной функцией
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); }
Я ожидаю, что вариант
foo(T&) requires...
быть предпочтительным автоматически как более ограниченный по сравнению с более общим вариантом
foo(T)
. И действительно, Clang и MSVC предпочитают его.
Но GCC продолжает жаловаться на двусмысленность 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; }
| ^~~
Помогите, пожалуйста, разобраться, какой из компиляторов здесь правильнее?