https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86860
Bug ID: 86860 Summary: Reject valid overloads of subclass ostream operator<< Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: mickey.veksler at gmail dot com Target Milestone: --- The following is rejected by gcc (not by other compilers): #include <sstream> #include <string> struct St : std::ostringstream { template<typename Tp> St& operator<<( const Tp& value ) { return *this; } operator std::string() const { return str(); } friend std::ostream& operator<<( std::ostream& s, const St& ss ) { return s << ss.str(); } }; struct Memory_type { std::string to_string() const { return St() << "s=" << s; } const char* s; }; Because of an ambiguity between user defined: template<typename Tp> St& operator<<( const Tp& value ) { return *this; } and GCC function defined (in ostream header): template<typename _Ostream, typename _Tp> inline typename enable_if<__and_<__not_<is_lvalue_reference<_Ostream>>, __is_convertible_to_basic_ostream<_Ostream>, __is_insertable< __rvalue_ostream_type<_Ostream>, const _Tp&>>::value, __rvalue_ostream_type<_Ostream>>::type operator<<(_Ostream&& __os, const _Tp& __x) { .... } The above function does not seem to be part of the standard, and it seems that the other compilers can work without it. This is described in https://stackoverflow.com/questions/51637953/what-enable-if-or-other-hint-is-need-for-the-following-overloaded-to-compile/51692662#51692662