https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84920
--- Comment #10 from Lewis Hyatt <lhyatt at gcc dot gnu.org> --- (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: ============= iowarn2.cpp: In function ‘void f(std::ostream&, const A<Y>&)’: iowarn2.cpp:13:5: error: no match for ‘operator<<’ (operand types are ‘std::ostream’ {aka ‘std::basic_ostream<char>’} and ‘const A<Y>’) 13 | o << a; | ~ ^~ ~ | | | | | const A<Y> | std::ostream {aka std::basic_ostream<char>} iowarn2.cpp:13:5: note: declining to output 34 candidates (limit 7); compile with ‘-foverload-candidates-stop-level=34’ to see them ============= With the suggestion from the diagnostic -foverload-candidates-stop-level=34, so this is the ~50% abbreviated mode: ============= iowarn2.cpp: In function ‘void f(std::ostream&, const A<Y>&)’: iowarn2.cpp:13:5: error: no match for ‘operator<<’ (operand types are ‘std::ostream’ {aka ‘std::basic_ostream<char>’} and ‘const A<Y>’) 13 | o << a; | ~ ^~ ~ | | | | | const A<Y> | std::ostream {aka std::basic_ostream<char>} In file included from iowarn2.cpp:1: /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:108:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(__ostream_type& (*)(__ostream_type&)) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:108:36: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘std::basic_ostream<char>::__ostream_type& (*)(std::basic_ostream<char>::__ostream_type&)’ {aka ‘std::basic_ostream<char>& (*)(std::basic_ostream<char>&)’} /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:117:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(__ios_type& (*)(__ios_type&)) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>; __ios_type = std::basic_ios<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:117:32: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘std::basic_ostream<char>::__ios_type& (*)(std::basic_ostream<char>::__ios_type&)’ {aka ‘std::basic_ios<char>& (*)(std::basic_ios<char>&)’} /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:127:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:127:30: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘std::ios_base& (*)(std::ios_base&)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:166:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:166:23: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘long int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:170:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:170:32: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘long unsigned int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:174:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:174:23: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘bool’ 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: ‘std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char; _Traits = std::char_traits<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:92:22: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘short int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:181:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:181:33: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘short unsigned int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:105:5: note: candidate: ‘std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char; _Traits = std::char_traits<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:106:20: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:192:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:192:31: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘unsigned int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:201:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:201:28: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘long long int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:205:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:205:37: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘long long unsigned int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:220:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:220:25: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘double’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:224:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:224:24: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘float’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:232:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:232:30: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘long double’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:245:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:245:30: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘const void*’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:250:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::nullptr_t) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>; std::nullptr_t = std::nullptr_t]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:250:18: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘std::nullptr_t’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:119:5: note: candidate: ‘std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(__streambuf_type*) [with _CharT = char; _Traits = std::char_traits<char>; __streambuf_type = std::basic_streambuf<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:120:34: note: no known conversion for argument 1 from ‘const A<Y>’ to ‘std::basic_ostream<char>::__streambuf_type*’ {aka ‘std::basic_streambuf<char>*’} iowarn2.cpp:5:6: note: candidate: ‘template<class T> decltype ((o << a.value)) operator<<(std::ostream&, const A<T>&)’ iowarn2.cpp:5:6: note: template argument deduction/substitution failed: iowarn2.cpp: In substitution of ‘template<class T> decltype ((o << a.value)) operator<<(std::ostream&, const A<T>&) [with T = Y]’: iowarn2.cpp:13:8: required from here iowarn2.cpp:6:15: error: no match for ‘operator<<’ (operand types are ‘std::ostream’ {aka ‘std::basic_ostream<char>’} and ‘const Y’) /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:108:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(__ostream_type& (*)(__ostream_type&)) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:108:36: note: no known conversion for argument 1 from ‘const Y’ to ‘std::basic_ostream<char>::__ostream_type& (*)(std::basic_ostream<char>::__ostream_type&)’ {aka ‘std::basic_ostream<char>& (*)(std::basic_ostream<char>&)’} /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:117:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(__ios_type& (*)(__ios_type&)) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>; __ios_type = std::basic_ios<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:117:32: note: no known conversion for argument 1 from ‘const Y’ to ‘std::basic_ostream<char>::__ios_type& (*)(std::basic_ostream<char>::__ios_type&)’ {aka ‘std::basic_ios<char>& (*)(std::basic_ios<char>&)’} /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:127:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:127:30: note: no known conversion for argument 1 from ‘const Y’ to ‘std::ios_base& (*)(std::ios_base&)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:166:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:166:23: note: no known conversion for argument 1 from ‘const Y’ to ‘long int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:170:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:170:32: note: no known conversion for argument 1 from ‘const Y’ to ‘long unsigned int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:174:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:174:23: note: no known conversion for argument 1 from ‘const Y’ to ‘bool’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:91:5: note: candidate: ‘std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char; _Traits = std::char_traits<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:92:22: note: no known conversion for argument 1 from ‘const Y’ to ‘short int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:181:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:181:33: note: no known conversion for argument 1 from ‘const Y’ to ‘short unsigned int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:105:5: note: candidate: ‘std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char; _Traits = std::char_traits<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:106:20: note: no known conversion for argument 1 from ‘const Y’ to ‘int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:192:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:192:31: note: no known conversion for argument 1 from ‘const Y’ to ‘unsigned int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:201:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:201:28: note: no known conversion for argument 1 from ‘const Y’ to ‘long long int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:205:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:205:37: note: no known conversion for argument 1 from ‘const Y’ to ‘long long unsigned int’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:220:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:220:25: note: no known conversion for argument 1 from ‘const Y’ to ‘double’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:224:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:224:24: note: no known conversion for argument 1 from ‘const Y’ to ‘float’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:232:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:232:30: note: no known conversion for argument 1 from ‘const Y’ to ‘long double’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:245:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:245:30: note: no known conversion for argument 1 from ‘const Y’ to ‘const void*’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:250:7: note: candidate: ‘std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::nullptr_t) [with _CharT = char; _Traits = std::char_traits<char>; __ostream_type = std::basic_ostream<char>; std::nullptr_t = std::nullptr_t]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:250:18: note: no known conversion for argument 1 from ‘const Y’ to ‘std::nullptr_t’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:119:5: note: candidate: ‘std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(__streambuf_type*) [with _CharT = char; _Traits = std::char_traits<char>; __streambuf_type = std::basic_streambuf<char>]’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:120:34: note: no known conversion for argument 1 from ‘const Y’ to ‘std::basic_ostream<char>::__streambuf_type*’ {aka ‘std::basic_streambuf<char>*’} 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: ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, basic_string_view<_CharT, _Traits>)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/string_view:672:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:15: note: ‘Y’ is not derived from ‘std::basic_string_view<_CharT, _Traits>’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/basic_string.h:3882:5: note: candidate: ‘template<class _CharT, class _Traits, class _Alloc> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/basic_string.h:3882:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:15: note: ‘const Y’ is not derived from ‘const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>’ 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: candidate: ‘template<class _IntegerType> constexpr std::__byte_op_t<_IntegerType> std::operator<<(byte, _IntegerType)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/cstddef:123:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:15: note: cannot convert ‘o’ (type ‘std::ostream’ {aka ‘std::basic_ostream<char>’}) to type ‘std::byte’ 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: ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const error_code&)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/system_error:329:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert ‘a.A<Y>::value’ (type ‘const Y’) to type ‘const std::error_code&’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:507:5: note: candidate: ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, _CharT)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:507:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:15: note: deduced conflicting types for parameter ‘_CharT’ (‘char’ and ‘Y’) /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:517:5: note: candidate: ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, char)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:517:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert ‘a.A<Y>::value’ (type ‘const Y’) to type ‘char’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:523:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, char)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:523:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert ‘a.A<Y>::value’ (type ‘const Y’) to type ‘char’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:534:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, signed char)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:534:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert ‘a.A<Y>::value’ (type ‘const Y’) to type ‘signed char’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:539:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, unsigned char)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:539:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert ‘a.A<Y>::value’ (type ‘const Y’) to type ‘unsigned char’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:598:5: note: candidate: ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const _CharT*)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:598:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:15: note: mismatched types ‘const _CharT*’ and ‘Y’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:302:5: note: candidate: ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const char*)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:302:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert ‘a.A<Y>::value’ (type ‘const Y’) to type ‘const char*’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:615:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, const char*)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:615:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert ‘a.A<Y>::value’ (type ‘const Y’) to type ‘const char*’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:628:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, const signed char*)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:628:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert ‘a.A<Y>::value’ (type ‘const Y’) to type ‘const signed char*’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:633:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, const unsigned char*)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:633:5: note: template argument deduction/substitution failed: iowarn2.cpp:6:20: note: cannot convert ‘a.A<Y>::value’ (type ‘const Y’) to type ‘const unsigned char*’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:754:5: note: candidate: ‘template<class _Ostream, class _Tp> _Ostream&& std::operator<<(_Ostream&&, const _Tp&)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:754:5: note: template argument deduction/substitution failed: /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream: In substitution of ‘template<class _Ostream, class _Tp> _Ostream&& std::operator<<(_Ostream&&, const _Tp&) [with _Ostream = std::basic_ostream<char>&; _Tp = Y]’: iowarn2.cpp:6:15: required by substitution of ‘template<class T> decltype ((o << a.value)) operator<<(std::ostream&, const A<T>&) [with T = Y]’ iowarn2.cpp:13:8: required from here /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:754:5: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’ iowarn2.cpp: In substitution of ‘template<class T> decltype ((o << a.value)) operator<<(std::ostream&, const A<T>&) [with T = Y]’: iowarn2.cpp:13:8: required from here iowarn2.cpp:5:6: note: candidate: ‘template<class T> decltype ((o << a.value)) operator<<(std::ostream&, const A<T>&)’ iowarn2.cpp:5:6: note: template argument deduction/substitution failed: iowarn2.cpp:6:15: note: ‘const Y’ is not derived from ‘const A<T>’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/string_view:672:5: note: candidate: ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, basic_string_view<_CharT, _Traits>)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/string_view:672:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: ‘A<Y>’ is not derived from ‘std::basic_string_view<_CharT, _Traits>’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/basic_string.h:3882:5: note: candidate: ‘template<class _CharT, class _Traits, class _Alloc> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const __cxx11::basic_string<_CharT, _Traits, _Allocator>&)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/basic_string.h:3882:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: ‘const A<Y>’ is not derived from ‘const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/cstddef:123:5: note: candidate: ‘template<class _IntegerType> constexpr std::__byte_op_t<_IntegerType> std::operator<<(byte, _IntegerType)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/cstddef:123:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:3: note: cannot convert ‘o’ (type ‘std::ostream’ {aka ‘std::basic_ostream<char>’}) to type ‘std::byte’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/system_error:329:5: note: candidate: ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const error_code&)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/system_error:329:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert ‘a’ (type ‘const A<Y>’) to type ‘const std::error_code&’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:507:5: note: candidate: ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, _CharT)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:507:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: deduced conflicting types for parameter ‘_CharT’ (‘char’ and ‘A<Y>’) /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:517:5: note: candidate: ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, char)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:517:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert ‘a’ (type ‘const A<Y>’) to type ‘char’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:523:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, char)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:523:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert ‘a’ (type ‘const A<Y>’) to type ‘char’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:534:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, signed char)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:534:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert ‘a’ (type ‘const A<Y>’) to type ‘signed char’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:539:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, unsigned char)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:539:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert ‘a’ (type ‘const A<Y>’) to type ‘unsigned char’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:598:5: note: candidate: ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const _CharT*)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:598:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: mismatched types ‘const _CharT*’ and ‘A<Y>’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:302:5: note: candidate: ‘template<class _CharT, class _Traits> std::basic_ostream<_CharT, _Traits>& std::operator<<(basic_ostream<_CharT, _Traits>&, const char*)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/bits/ostream.tcc:302:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert ‘a’ (type ‘const A<Y>’) to type ‘const char*’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:615:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, const char*)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:615:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert ‘a’ (type ‘const A<Y>’) to type ‘const char*’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:628:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, const signed char*)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:628:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert ‘a’ (type ‘const A<Y>’) to type ‘const signed char*’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:633:5: note: candidate: ‘template<class _Traits> std::basic_ostream<char, _Traits>& std::operator<<(basic_ostream<char, _Traits>&, const unsigned char*)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:633:5: note: template argument deduction/substitution failed: iowarn2.cpp:13:8: note: cannot convert ‘a’ (type ‘const A<Y>’) to type ‘const unsigned char*’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:754:5: note: candidate: ‘template<class _Ostream, class _Tp> _Ostream&& std::operator<<(_Ostream&&, const _Tp&)’ /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:754:5: note: template argument deduction/substitution failed: /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream: In substitution of ‘template<class _Ostream, class _Tp> _Ostream&& std::operator<<(_Ostream&&, const _Tp&) [with _Ostream = std::basic_ostream<char>&; _Tp = A<Y>]’: iowarn2.cpp:13:8: required from here /home/lewis/gccdev/dev/rel/include/c++/13.0.0/ostream:754:5: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’ ============= 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-pastable option to see more. The intermediate option above which omits the source line feels also like it still conveys enough information to me, say the user's code with decltype etc is still printed because it's part of the diagnostic message 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.