Reputation: 4732
Is the call to f
ambiguous? Since one of the functions is more constrained than
the other, I wouldn't expect there to be any ambiguity. Yet, GCC 12.2
and Clang trunk
reject the
code, in contrast to Clang 15
, MSVC 19.33
, and MSVC trunk
.
template<typename...>
int f();
template<typename = void>
int f() requires true;
static_assert(sizeof(f()));
The error produced by GCC:
<source>:7:23: error: call of overloaded 'f()' is ambiguous
7 | static_assert(sizeof(f()));
| ~^~
<source>:2:5: note: candidate: 'int f() [with <template-parameter-1-1> = {}]'
2 | int f();
| ^
<source>:5:5: note: candidate: 'int f() requires true [with <template-parameter-1-1> = void]'
5 | int f() requires true;
| ^
Upvotes: 5
Views: 186
Reputation: 76678
Whether viable overloads from function templates are more constrained is considered only if the function templates are otherwise equivalent (except for potentially the return type). It is not sufficient that the call would otherwise be ambiguous.
In particular the corresponding template parameters must be equivalent, see [temp.func.order]/6.2.2. A template parameter that is a parameter pack (as in the first overload) is not equivalent to one that isn't (as in the second overload), see [temp.over.link]/6.2.
So the constraint doesn't matter for deciding which candidate is better. The call is ambiguous.
Upvotes: 2