https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67499
--- Comment #7 from Manuel López-Ibáñez <manu at gcc dot gnu.org> --- (In reply to Marc Glisse from comment #6) > In the example above, you dropped the > information that it is 'bar' (the second argument) that cannot be converted, > which, for a function with more arguments and templates and typedefs all > over the place, might not be obvious at all. This info is already implied by the error: test.cc:5:15: error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘foo’) std::cout << bar; ^ It is also inconsistently printed for some conversions: /usr/include/c++/4.8/ostream:543:5: note: template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const signed char*) operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s) ^ /usr/include/c++/4.8/ostream:543:5: note: template argument deduction/substitution failed: test.cc:5:18: note: cannot convert ‘bar’ (type ‘foo’) to type ‘const signed char*’ std::cout << bar; ^ but not for others: /usr/include/c++/4.8/ostream:245:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char; _Trai ts = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>] operator<<(const void* __p) ^ /usr/include/c++/4.8/ostream:245:7: note: no known conversion for argument 1 from ‘foo’ to ‘const void*’ Note that I'm ok with printing: /usr/include/c++/4.8/ostream:543:5: note: template argument deduction/substitution failed: cannot convert ‘bar’ (type ‘foo’) to type ‘const signed char*’ or even: /usr/include/c++/4.8/ostream:543:5: note: template argument deduction/substitution failed: cannot convert ‘bar’ (type ‘foo’) to type ‘const signed char*’ for argument 1 My point is to not print: test.cc:5:18: note: X std::cout << bar; ^ for the error AND for every candidate. For example, we could print: test.cc:5:15: error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘foo’) std::cout << bar; ^ test.cc:5:18: note: template argument deduction/substitution failed: cannot convert ‘bar’ (type ‘foo’) std::cout << bar; ^ /usr/include/c++/4.8/ostream:245:7: note: candidate 1: no known conversion for argument 1 from ‘foo’ to ‘const void*’ for 'std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]' operator<<(const void* __p) ^ /usr/include/c++/4.8/ostream:543:5: note: candidate 2: cannot convert type ‘foo’ to type ‘const signed char*’ for 'template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(std::basic_ostream<char, _Traits>&, const signed char*)' operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s) ^ [etc.] > If we were outputting html, it would be much easier, we could print the > error message and have javascript so that clicking in appropriate places > displays the candidates, the reason for substitution failure, what a type is > an alias for, etc. This is something IDEs could do. But with text, we have > to print everything that might be useful. We could still print it in a smarter, nicer looking and consistent way, without repeating the same info several times (in the example above, there are only 108 unique lines out of 193).