From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 9B27938344DB; Thu, 9 Jun 2022 13:37:32 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9B27938344DB From: "lhyatt at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/84920] Better handling of unmatched/ambiguous calls Date: Thu, 09 Jun 2022 13:37:32 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c++ X-Bugzilla-Version: 8.0 X-Bugzilla-Keywords: diagnostic X-Bugzilla-Severity: normal X-Bugzilla-Who: lhyatt at gcc dot gnu.org X-Bugzilla-Status: ASSIGNED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: dmalcolm at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 09 Jun 2022 13:37:32 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D84920 --- Comment #10 from Lewis Hyatt --- (In reply to Jonathan Wakely from comment #9) > That looks pretty good to me. What does it produce for the operator<< > example in comment 1? With the default options: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D iowarn2.cpp: In function =E2=80=98void f(std::ostream&, const A&)=E2=80= =99: iowarn2.cpp:13:5: error: no match for =E2=80=98operator<<=E2=80=99 (operand= types are =E2=80=98std::ostream=E2=80=99 {aka =E2=80=98std::basic_ostream=E2=80= =99} and =E2=80=98const A=E2=80=99) 13 | o << a; | ~ ^~ ~ | | | | | const A | std::ostream {aka std::basic_ostream} iowarn2.cpp:13:5: note: declining to output 34 candidates (limit 7); compile with =E2=80=98-foverload-candidates-stop-level=3D34=E2=80=99 to see them =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D With the suggestion from the diagnostic -foverload-candidates-stop-level=3D= 34, so this is the ~50% abbreviated mode: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D iowarn2.cpp: In function =E2=80=98void f(std::ostream&, const A&)=E2=80= =99: iowarn2.cpp:13:5: error: no match for =E2=80=98operator<<=E2=80=99 (operand= types are =E2=80=98std::ostream=E2=80=99 {aka =E2=80=98std::basic_ostream=E2=80= =99} and =E2=80=98const A=E2=80=99) 13 | o << a; | ~ ^~ ~ | | | | | const A | std::ostream {aka std::basic_ostream} In file included from iowarn2.cpp:1: /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:108:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(__ostream_type& (*)(__ostream_type&)) [with _CharT =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:108:36: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98std::basic_ostream::__ostream_type& (*)(std::basic_ostream::__ostream_type&)=E2=80=99 {aka =E2=80=98std::= basic_ostream& (*)(std::basic_ostream&)=E2=80=99} /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:117:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(__ios_type& (*)(__ios_type&= )) [with _CharT =3D char; _Traits =3D std::char_traits; __ostream_type = =3D std::basic_ostream; __ios_type =3D std::basic_ios]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:117:32: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98std::basic_ostream::__ios_type& (*)(std::basic_ostream::__ios_type&)=E2=80=99 {aka =E2=80=98std::basi= c_ios& (*)(std::basic_ios&)=E2=80=99} /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:127:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [with _CharT =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:127:30: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98std= ::ios_base& (*)(std::ios_base&)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:166:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT =3D = char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:166:23: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98lon= g int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:170:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _C= harT =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:170:32: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98lon= g unsigned int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:174:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:174:23: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98boo= l=E2=80=99 In file included from /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:833: /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:91:5: note: candidate: =E2=80=98std::basic_ostream<_CharT, _Traits>& std::basic_ostream= <_CharT, _Traits>::operator<<(short int) [with _CharT =3D char; _Traits =3D std::char_traits]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:92:22: note:= =20=20 no known conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2= =80=98short int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:181:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:181:33: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98sho= rt unsigned int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:105:5: note: candidate: =E2=80=98std::basic_ostream<_CharT, _Traits>& std::basic_ostream= <_CharT, _Traits>::operator<<(int) [with _CharT =3D char; _Traits =3D std::char_traits]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:106:20: note= :=20=20 no known conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2= =80=98int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:192:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:192:31: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98uns= igned int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:201:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT= =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:201:28: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98lon= g long int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:205:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [wi= th _CharT =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:205:37: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98lon= g long unsigned int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:220:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT =3D ch= ar; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:220:25: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98dou= ble=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:224:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT =3D cha= r; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:224:24: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98flo= at=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:232:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:232:30: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98lon= g double=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:245:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:245:30: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98con= st void*=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:250:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::nullptr_t) [with _Char= T =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream; std::nullptr_t =3D std::nullptr_t]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:250:18: note: no kn= own conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98std= ::nullptr_t=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:119:5: note: candidate: =E2=80=98std::basic_ostream<_CharT, _Traits>& std::basic_ostream= <_CharT, _Traits>::operator<<(__streambuf_type*) [with _CharT =3D char; _Traits =3D std::char_traits; __streambuf_type =3D std::basic_streambuf]=E2= =80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:120:34: note= :=20=20 no known conversion for argument 1 from =E2=80=98const A=E2=80=99 to =E2=80=98std::basic_ostream::__streambuf_type*=E2=80=99 {aka =E2=80=98std::basic_streambuf*=E2=80=99} iowarn2.cpp:5:6: note: candidate: =E2=80=98template decltype ((o <= < a.value)) operator<<(std::ostream&, const A&)=E2=80=99 iowarn2.cpp:5:6: note: template argument deduction/substitution failed: iowarn2.cpp: In substitution of =E2=80=98template decltype ((o << = a.value)) operator<<(std::ostream&, const A&) [with T =3D Y]=E2=80=99: iowarn2.cpp:13:8: required from here iowarn2.cpp:6:15: error: no match for =E2=80=98operator<<=E2=80=99 (operand= types are =E2=80=98std::ostream=E2=80=99 {aka =E2=80=98std::basic_ostream=E2=80= =99} and =E2=80=98const Y=E2=80=99) /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:108:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(__ostream_type& (*)(__ostream_type&)) [with _CharT =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:108:36: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98std::basic_ostream::__ostream_type& (*)(std::basic_ostream::__ostream_type&)=E2=80=99 {aka =E2=80=98std::= basic_ostream& (*)(std::basic_ostream&)=E2=80=99} /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:117:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(__ios_type& (*)(__ios_type&= )) [with _CharT =3D char; _Traits =3D std::char_traits; __ostream_type = =3D std::basic_ostream; __ios_type =3D std::basic_ios]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:117:32: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98std::basic_ostream::__ios_type& (*)(std::basic_ostream::__ios_type&)=E2=80=99 {aka =E2=80=98std::basi= c_ios& (*)(std::basic_ios&)=E2=80=99} /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:127:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [with _CharT =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:127:30: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98std::i= os_base& (*)(std::ios_base&)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:166:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT =3D = char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:166:23: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98long i= nt=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:170:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _C= harT =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:170:32: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98long u= nsigned int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:174:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:174:23: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98bool= =E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:91:5: note: candidate: =E2=80=98std::basic_ostream<_CharT, _Traits>& std::basic_ostream= <_CharT, _Traits>::operator<<(short int) [with _CharT =3D char; _Traits =3D std::char_traits]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:92:22: note:= =20=20 no known conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80= =98short int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:181:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:181:33: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98short = unsigned int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:105:5: note: candidate: =E2=80=98std::basic_ostream<_CharT, _Traits>& std::basic_ostream= <_CharT, _Traits>::operator<<(int) [with _CharT =3D char; _Traits =3D std::char_traits]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:106:20: note= :=20=20 no known conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80= =98int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:192:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:192:31: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98unsign= ed int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:201:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT= =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:201:28: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98long l= ong int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:205:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [wi= th _CharT =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:205:37: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98long l= ong unsigned int=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:220:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT =3D ch= ar; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:220:25: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98double= =E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:224:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT =3D cha= r; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:224:24: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98float= =E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:232:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:232:30: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98long d= ouble=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:245:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:245:30: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98const = void*=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:250:7: note: candidat= e: =E2=80=98std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::nullptr_t) [with _Char= T =3D char; _Traits =3D std::char_traits; __ostream_type =3D std::basic_ostream; std::nullptr_t =3D std::nullptr_t]=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:250:18: note: no kn= own conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98std::n= ullptr_t=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:119:5: note: candidate: =E2=80=98std::basic_ostream<_CharT, _Traits>& std::basic_ostream= <_CharT, _Traits>::operator<<(__streambuf_type*) [with _CharT =3D char; _Traits =3D std::char_traits; __streambuf_type =3D std::basic_streambuf]=E2= =80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:120:34: note= :=20=20 no known conversion for argument 1 from =E2=80=98const Y=E2=80=99 to =E2=80=98std::basic_ostream::__streambuf_type*=E2=80=99 {aka =E2=80=98std::basic_streambuf*=E2=80=99} In file included from /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/basic_string.h:47, from /home/lewis/gccdev/dev/rel/include/c++/13.0.0/string:= 52, from /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/locale_classes.h:40, from /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ios_base.h:41, from /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ios:42, from /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream= :38: /home/lewis/gccdev/dev/rel/include/c++/13.0.0/string_view:672:5: note: candidate: =E2=80=98template std::basic_ostrea= m<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, basic_string_view<_CharT, _Traits>)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/string_view:672:5: note:=20=20 template argument deduction/substitution failed: iowarn2.cpp:6:15: note: =E2=80=98Y=E2=80=99 is not derived from =E2=80=98std::basic_string_view<_CharT, _Traits>=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/basic_string.h:3882:5: n= ote: candidate: =E2=80=98template std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)=E2=80= =99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/basic_string.h:3882:5: n= ote: template argument deduction/substitution failed: iowarn2.cpp:6:15: note: =E2=80=98const Y=E2=80=99 is not derived from =E2= =80=98const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>=E2=80=99 In file included from /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/memory_resource.h:38, from /home/lewis/gccdev/dev/rel/include/c++/13.0.0/string:= 56: /home/lewis/gccdev/dev/rel/include/c++/13.0.0/cstddef:123:5: note: candidat= e: =E2=80=98template constexpr std::__byte_op_t<_IntegerTy= pe> std::operator<<(byte, _IntegerType)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/cstddef:123:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:6:15: note: cannot convert =E2=80=98o=E2=80=99 (type =E2=80= =98std::ostream=E2=80=99 {aka =E2=80=98std::basic_ostream=E2=80=99}) to type =E2=80=98std::byte=E2= =80=99 In file included from /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ios_base.h:46: /home/lewis/gccdev/dev/rel/include/c++/13.0.0/system_error:329:5: note: candidate: =E2=80=98template std::basic_ostrea= m<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const error_code= &)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/system_error:329:5: note:=20= =20 template argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert =E2=80=98a.A::value=E2=80=99 (t= ype =E2=80=98const Y=E2=80=99) to type =E2=80=98const std::error_code&=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:507:5: note: candidat= e: =E2=80=98template std::basic_ostream<_CharT, _= Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, _CharT)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:507:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:6:15: note: deduced conflicting types for parameter =E2=80=98= _CharT=E2=80=99 (=E2=80=98char=E2=80=99 and =E2=80=98Y=E2=80=99) /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:517:5: note: candidat= e: =E2=80=98template std::basic_ostream<_CharT, _= Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, char)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:517:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert =E2=80=98a.A::value=E2=80=99 (t= ype =E2=80=98const Y=E2=80=99) to type =E2=80=98char=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:523:5: note: candidat= e: =E2=80=98template std::basic_ostream& std::operator<<(basic_ostream&, char)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:523:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert =E2=80=98a.A::value=E2=80=99 (t= ype =E2=80=98const Y=E2=80=99) to type =E2=80=98char=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:534:5: note: candidat= e: =E2=80=98template std::basic_ostream& std::operator<<(basic_ostream&, signed char)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:534:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert =E2=80=98a.A::value=E2=80=99 (t= ype =E2=80=98const Y=E2=80=99) to type =E2=80=98signed char=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:539:5: note: candidat= e: =E2=80=98template std::basic_ostream& std::operator<<(basic_ostream&, unsigned char)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:539:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert =E2=80=98a.A::value=E2=80=99 (t= ype =E2=80=98const Y=E2=80=99) to type =E2=80=98unsigned char=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:598:5: note: candidat= e: =E2=80=98template std::basic_ostream<_CharT, _= Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const _CharT*)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:598:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:6:15: note: mismatched types =E2=80=98const _CharT*=E2=80=99 = and =E2=80=98Y=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:302:5: note: candidate: =E2=80=98template std::basic_ostrea= m<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const char*)=E2= =80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:302:5: note:= =20=20 template argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert =E2=80=98a.A::value=E2=80=99 (t= ype =E2=80=98const Y=E2=80=99) to type =E2=80=98const char*=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:615:5: note: candidat= e: =E2=80=98template std::basic_ostream& std::operator<<(basic_ostream&, const char*)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:615:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert =E2=80=98a.A::value=E2=80=99 (t= ype =E2=80=98const Y=E2=80=99) to type =E2=80=98const char*=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:628:5: note: candidat= e: =E2=80=98template std::basic_ostream& std::operator<<(basic_ostream&, const signed char*)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:628:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert =E2=80=98a.A::value=E2=80=99 (t= ype =E2=80=98const Y=E2=80=99) to type =E2=80=98const signed char*=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:633:5: note: candidat= e: =E2=80=98template std::basic_ostream& std::operator<<(basic_ostream&, const unsigned char*)=E2=80= =99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:633:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert =E2=80=98a.A::value=E2=80=99 (t= ype =E2=80=98const Y=E2=80=99) to type =E2=80=98const unsigned char*=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:754:5: note: candidat= e: =E2=80=98template _Ostream&& std::operator<<(_Os= tream&&, const _Tp&)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:754:5: note: templa= te argument deduction/substitution failed: /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream: In substitution of =E2=80=98template _Ostream&& std::operator<<(_Os= tream&&, const _Tp&) [with _Ostream =3D std::basic_ostream&; _Tp =3D Y]=E2=80= =99: iowarn2.cpp:6:15: required by substitution of =E2=80=98template = decltype ((o << a.value)) operator<<(std::ostream&, const A&) [with T =3D Y]=E2=80=99 iowarn2.cpp:13:8: required from here /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:754:5: error: no type named =E2=80=98type=E2=80=99 in =E2=80=98struct std::enable_if= =E2=80=99 iowarn2.cpp: In substitution of =E2=80=98template decltype ((o << = a.value)) operator<<(std::ostream&, const A&) [with T =3D Y]=E2=80=99: iowarn2.cpp:13:8: required from here iowarn2.cpp:5:6: note: candidate: =E2=80=98template decltype ((o <= < a.value)) operator<<(std::ostream&, const A&)=E2=80=99 iowarn2.cpp:5:6: note: template argument deduction/substitution failed: iowarn2.cpp:6:15: note: =E2=80=98const Y=E2=80=99 is not derived from =E2= =80=98const A=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/string_view:672:5: note: candidate: =E2=80=98template std::basic_ostrea= m<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, basic_string_view<_CharT, _Traits>)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/string_view:672:5: note:=20=20 template argument deduction/substitution failed: iowarn2.cpp:13:8: note: =E2=80=98A=E2=80=99 is not derived from =E2=80=98std::basic_string_view<_CharT, _Traits>=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/basic_string.h:3882:5: n= ote: candidate: =E2=80=98template std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)=E2=80= =99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/basic_string.h:3882:5: n= ote: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: =E2=80=98const A=E2=80=99 is not derived from = =E2=80=98const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/cstddef:123:5: note: candidat= e: =E2=80=98template constexpr std::__byte_op_t<_IntegerTy= pe> std::operator<<(byte, _IntegerType)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/cstddef:123:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:13:3: note: cannot convert =E2=80=98o=E2=80=99 (type =E2=80= =98std::ostream=E2=80=99 {aka =E2=80=98std::basic_ostream=E2=80=99}) to type =E2=80=98std::byte=E2= =80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/system_error:329:5: note: candidate: =E2=80=98template std::basic_ostrea= m<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const error_code= &)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/system_error:329:5: note:=20= =20 template argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert =E2=80=98a=E2=80=99 (type =E2=80= =98const A=E2=80=99) to type =E2=80=98const std::error_code&=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:507:5: note: candidat= e: =E2=80=98template std::basic_ostream<_CharT, _= Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, _CharT)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:507:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:13:8: note: deduced conflicting types for parameter =E2=80=98= _CharT=E2=80=99 (=E2=80=98char=E2=80=99 and =E2=80=98A=E2=80=99) /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:517:5: note: candidat= e: =E2=80=98template std::basic_ostream<_CharT, _= Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, char)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:517:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert =E2=80=98a=E2=80=99 (type =E2=80= =98const A=E2=80=99) to type =E2=80=98char=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:523:5: note: candidat= e: =E2=80=98template std::basic_ostream& std::operator<<(basic_ostream&, char)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:523:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert =E2=80=98a=E2=80=99 (type =E2=80= =98const A=E2=80=99) to type =E2=80=98char=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:534:5: note: candidat= e: =E2=80=98template std::basic_ostream& std::operator<<(basic_ostream&, signed char)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:534:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert =E2=80=98a=E2=80=99 (type =E2=80= =98const A=E2=80=99) to type =E2=80=98signed char=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:539:5: note: candidat= e: =E2=80=98template std::basic_ostream& std::operator<<(basic_ostream&, unsigned char)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:539:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert =E2=80=98a=E2=80=99 (type =E2=80= =98const A=E2=80=99) to type =E2=80=98unsigned char=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:598:5: note: candidat= e: =E2=80=98template std::basic_ostream<_CharT, _= Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const _CharT*)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:598:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:13:8: note: mismatched types =E2=80=98const _CharT*=E2=80=99 = and =E2=80=98A=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:302:5: note: candidate: =E2=80=98template std::basic_ostrea= m<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const char*)=E2= =80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:302:5: note:= =20=20 template argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert =E2=80=98a=E2=80=99 (type =E2=80= =98const A=E2=80=99) to type =E2=80=98const char*=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:615:5: note: candidat= e: =E2=80=98template std::basic_ostream& std::operator<<(basic_ostream&, const char*)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:615:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert =E2=80=98a=E2=80=99 (type =E2=80= =98const A=E2=80=99) to type =E2=80=98const char*=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:628:5: note: candidat= e: =E2=80=98template std::basic_ostream& std::operator<<(basic_ostream&, const signed char*)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:628:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert =E2=80=98a=E2=80=99 (type =E2=80= =98const A=E2=80=99) to type =E2=80=98const signed char*=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:633:5: note: candidat= e: =E2=80=98template std::basic_ostream& std::operator<<(basic_ostream&, const unsigned char*)=E2=80= =99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:633:5: note: templa= te argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert =E2=80=98a=E2=80=99 (type =E2=80= =98const A=E2=80=99) to type =E2=80=98const unsigned char*=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:754:5: note: candidat= e: =E2=80=98template _Ostream&& std::operator<<(_Os= tream&&, const _Tp&)=E2=80=99 /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:754:5: note: templa= te argument deduction/substitution failed: /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream: In substitution of =E2=80=98template _Ostream&& std::operator<<(_Os= tream&&, const _Tp&) [with _Ostream =3D std::basic_ostream&; _Tp =3D A]=E2= =80=99: iowarn2.cpp:13:8: required from here /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:754:5: error: no type named =E2=80=98type=E2=80=99 in =E2=80=98struct std::enable_if= =E2=80=99 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D I guess everyone will have a different option based on their workflow, but = FWIW I prefer the default output to be very short, along with an easy copy-pasta= ble option to see more. The intermediate option above which omits the source li= ne feels also like it still conveys enough information to me, say the user's c= ode with decltype etc is still printed because it's part of the diagnostic mess= age too. I'm happy to tweak it, also if you think it makes sense to handle say system header locations or namespace std specially, I could do that too. I = was trying to avoid that and rather use the large number of overloads as an indicator of "this is probably not worth printing", because special-casing = the standard library wouldn't help with other heavily templated libraries like boost.=