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

Reply via email to