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

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Nathan Ridge from comment #0)
> 1. Template argument deduction/substitution is failing because of a
> *warning*? The following reduced example:
> 
>     struct string
>     {
>         string(char*);
>     };
> 
>     template <typename T>
>     void operator+(const string&, const T&);
>     
>     struct T
>     {
>         enum {value = 0};
>     };
>     
>     int main()
>     {
>         return 0 + T::value; 
>     }
> 
> gives a similar warning but no errors. It is inconsistent for an ambiguity
> to cause just a warning in one case, and failure of template argument
> deduction/substitution in another.

That's by design. G++ extensions that change the meaning of ill-formed code are
disabled in SFINAE contexts. This is similar to the -Wnarrowing option, for
which the manual says:

"Note that this does not affect the meaning of well-formed code; narrowing
conversions are still considered ill-formed in SFINAE contexts."

This ensures that static properties of the code (e.g. detectable using decltype
or other compile-time metaprogramming) are consistent with other compilers that
don't implement the same non-standard extension.

> 2. There is no caret diagnostic associated with the "ISO C++ says that these
> are ambiguous" warning, so it's difficult to tell what "these" are. (We can
> infer from the candidates being operator+, but there could have been many
> uses of operator+ in that expression, and only one of them ambiguous, so it
> would be nice to have a caret pointing to that one).

I can't reproduce this part of the report, I see a location for the ambiguity,
with all versions I tested from 4.8.0 onwards:

a.cc:19:5: warning: ISO C++ says that these are ambiguous, even though the
worst conversion for the first is better than the worst conversion for the
second: [enabled by default]
 S<0 + T<X>::value> foo(X);
     ^

Since GCC 6 it's a range not a single location:

a.cc:19:5: warning: ISO C++ says that these are ambiguous, even though the
worst conversion for the first is better than the worst conversion for the
second:
 S<0 + T<X>::value> foo(X);
   ~~^~~~~~

And with current trunk the range is correct :-)

a.cc:19:5: warning: ISO C++ says that these are ambiguous, even though the
worst conversion for the first is better than the worst conversion for the
second:
   19 | S<0 + T<X>::value> foo(X);
      |   ~~^~~~~~~~~~~~~

Reply via email to