https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102283

--- Comment #3 from Patrick Palka <ppalka at gcc dot gnu.org> ---
(In reply to Giuseppe D'Angelo from comment #2)
> Hi,
> 
> Do you think that in my original testcase the call should be rejected as
> ambiguous as well? (It seems "reasonable" to me, but maybe I'm missing some
> niche detail about overload resolution when combined with template
> deduction.)
> 
> 
> This small variation over the testcase:
> 
> 
> struct A { };
> struct B { };
> 
> template <typename T = A>
> void f(T &&); // #1
> void f(const B&) = delete; // #2
> 
> int main() {
>   f({});
> }
> 
> This now makes GCC select #2, and fail to compile because it's deleted;

I think this is because GCC considers the two ICSes to be incomparable, but
then #2 wins over #1 anyway because non-templates are preferred over templates
(as per [over.match.best]).

Whereas with Clang/MSVC, I presume they consider the ICS for #1 to be better
than that for #2 (though I haven't found the wording in the standard that
supports this), so #1 wins during the ICS comparison stage of overload
resolution.

> Clang and MSVC still select #1. But a further, minor change:
> 
> 
> struct A { };
> struct B { };
> 
> template <typename T = int> // <-- changed this
> void f(T &&); // #1
> void f(const B&) = delete; // #2
> 
> int main() {
>   f({});
> }
> 
> makes GCC select #1...

This example is a different because the ICS for #1 is a standard conversion
sequence (since the {} initializes a non-class) whereas for #2 it's a
user-defined conversion sequence (since the {} initializes a class), and the
former kind is always better than the latter.  So #1 wins due to having the
better ICS.

Reply via email to