c++linuxgccnetbeansostream

No match for ‘operator<<’ (probably due to my version of c++/gcc?)


I’m a C++ newbie. I’ve tried to set up NetBeans and run a c++ program in my MacBook Air via virtual machine (UTM) lately. It works well in my company's Linux desktop, but somehow it just doesn’t work in my virtual Linux. The source code is the same in these two platforms, but they have different compilation result. One is fine, and the other shows the error message below.

error: no match for ‘operator<<’

I was wondering if it is due to the version mismatch or something similar of these two Linux environment. By the way, the author of this program has left the company, so I am doing my best to understand the his code. I’ve seen several posts here about this exactly the same issue, but it seems none of those solutions can work with my situation where this source code works well in one Linux while it doesn’t work in another one.

Below is the error message and relevant source codes. Could you please help me look into them? Thanks a lot!

Source code:

class logger
    {
      public:
        typedef std::ostringstream collector_stream_type;

      private:
        collector_stream_type _os;
        log_levels _messageLevel;

       public:
           logger(const logger & r) : _messageLevel(r._messageLevel)
              {
                   if ( do_log() ) _os << r._os; // this is where the error occurs.
               }
    }

Error / Warning message from NetBeans

In file included from

  • error: no match for ‘operator<<’ (operand types are ‘MySoftware::log::logger::collector_stream_type’ {aka ‘std::__cxx11::basic_ostringstream’} and ‘const collector_stream_type’ {aka ‘const std::__cxx11::basic_ostringstream’})
  • note: cannot convert ‘r.MySoftware::log::logger::_os’ (type ‘const collector_stream_type’ {aka ‘const std::__cxx11::basic_ostringstream’}) to type ‘const std::error_code&’
  • note: ‘const collector_stream_type’ {aka ‘const std::__cxx11::basic_ostringstream’} is not derived from ‘const std::complex<_Tp>’
  • note: cannot convert ‘((MySoftware::log::logger*)this)->MySoftware::log::logger::_os’ (type ‘MySoftware::log::logger::collector_stream_type’ {aka ‘std::__cxx11::basic_ostringstream’}) to type ‘std::byte’
  • note: candidate: ‘operator<<(int, int)’ (built-in)
  • note: ‘const collector_stream_type’ {aka ‘const std::__cxx11::basic_ostringstream’} is not derived from ‘const std::__shared_ptr<_Tp, _Lp>’
  • note: deduced conflicting types for parameter ‘_CharT’ (‘char’ and ‘std::__cxx11::basic_ostringstream’...

Solution

  • This was probably always wrong (assuming there isn't some user-defined operator<< overload candidate hiding somewhere in your code).

    There is and never has been any overload of operator<< in the standard library that would take two std::ostringstream or related types as parameters.

    Instead before C++11 the chosen overload would be

    std::basic_ostream::operator<<(const void*)
    

    because the std::basic_ios base class of the right-hand std::ostringstream of _os << r._os had a conversion function to void* that could implicitly convert r._os to void*. The result would be a null pointer if the stream is in a fail() state and any other pointer value otherwise.

    The result is that _os << r._os will write to _os a numeric representation of a null pointer if r._os is in a fail() state and any other numeric representation of a pointer value otherwise.

    That doesn't seem intended.

    Since C++11 the conversion function has been changed to convert to bool instead and has been made explicit so that it isn't viable any more for an implicit conversion to use the operator<<(const void*) overload. The change is meant to prevent exactly such mistakes.


    Side note: The error messages are not from Netbeans. Netbeans is your IDE. The error messages are from your compiler, which seems to be GCC according to what you wrote.