This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/84920] Better handling of unmatched/ambiguous calls


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

--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to David Malcolm from comment #0)
> As reported by user "jcoffland" on Hacker News:
> https://news.ycombinator.com/item?id=16598071
> 
> > One improvement I'd like to see is a simplified error message
> > for mismatched overloaded calls. If you make an overloaded call
> > for which the is no matching conversion or if the conversation is
> > ambiguous the compiler will "helpfully" dump a list of possibly
> > matching overloaded function signatures. The list can be hundreds
> > of lines long.

It's rare to get hundreds of lines in general. That usually only happens for
iostream operator<< and operator>>, because not many operators have as many
overloads all in the same namespace. But a general solution wouldn't hurt. 


> > For example, when you try to pipe a class to std::cout that
> > doesn't have an std::ostream &operator<<(std::ostream &, const X &).
> > Perhaps instead of dumping the complete function signatures it
> > could show one function signature followed by a list of types
> > accepted as the second parameter. Since the signatures are
> > otherwise the same.

I like the idea, but this isn't *strictly* true, as there's a function template
taking an rvalue stream as the first parameter, but that should accept all the
same types as the version for lvalue streams, so showing it doesn't add much
value.

The other advantages of the signatures is that they include the location info,
so if an overload doesn't match because of a SFINAE constraint you can go and
check the source, e.g. given

#include <ostream>
template<typename T> struct A { T value; };

template<typename T>
auto operator<<(std::ostream& o, const A<T>& a)
-> decltype(o << a.value)
{ return o << a.value; }

struct Y { };

void f(std::ostream& o, const A<Y>& a)
{
  o << a;
}

Included in the output is:

a.cc:5:6: note: candidate: template<class T> decltype ((o << a.value))
operator<<(std::ostream&, const A<T>&)
 auto operator<<(std::ostream& o, const A<T>& a)
      ^~~~~~~~
a.cc:5:6: note:   template argument deduction/substitution failed:
a.cc: In substitution of ‘template<class T> decltype ((o << a.value))
operator<<(std::ostream&, const A<T>&) [with T = Y]’:
a.cc:13:8:   required from here
a.cc:6:15: error: no match for ‘operator<<’ (operand types are ‘std::ostream
{aka std::basic_ostream<char>}’ and ‘const Y’)
 -> decltype(o << a.value)
             ~~^~~~~~~~~~

which points to a.cc:5:6 as the location of the overload, and the expression at
a.cc:6:15 is potentially useful infomration.

Maybe we could special-case the overloads from namespace std, since they are
usually less interesting. Usually.


More generally, maybe add -foverload-candidates-limit=N so if the overload set
is above the limit don't show the notes with the reasons overload resolution
failed, just show the candidates.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]