简体   繁体   中英

stream operators where lhs is not a std::iostream instance

I have a custom output class that has two std::ostream members that serve different purposes. Either stream is used depending upon how the output class is configured. In some instances, the two streams are chained together. A grossly simplified version of the class is below. I can provide some more details if needed.

class c_Output
{
  public:
    c_Output (bool x_useA) : m_useA(x_useA) { /* setup m_stream[AB] here */ };
    ~c_Output ();
    inline std::ostream& stream () { return (m_useA ? m_streamA : m_streamB); };

  private:
    bool m_useA;
    std::ostream m_streamA;
    std::ostream m_streamB;
}

I know how to write stream operators for classes that I wish to stream to/from std::cout , std::cin , or any other std::iostream , but I am struggling to write stream operators where a c_Output instance serves as the lhs instead of a std::ostream instance.

Right now, I am able to get away with:

c_Output l_output;
uint64_t l_value = 0xc001c0de;
l_output.stream() << std::hex << std::setw(16) << std::setfill('0') << l_value;

c_Output::stream() returns the appropriate std::ostream& , so this behaves just as expected.

I would like to rewrite the above as:

c_Output l_output;
uint64_t l_value = 0xc001c0de;
l_output << std::hex << std::setw(16) << std::setfill('0') << l_value;

I have attempted several different versions of defining operator<< based on examples I have seen here on StackOverflow and the greater web to no avail. The latest version looks like this:

// in header
class c_Output
{
    ...
    friend c_Output& operator<< (c_Output& x_output, std::ostream& x_stream);
    ...
}

// in source
c_Output&
operator<< (c_Output& x_output, std::ostream& x_stream)
{
    x_output.stream() << x_stream;
    return x_output;
}

The setup of the arguments is intended to mirror the standard stream operator overload. This setup gives me compile issues such as:

error: no match for 'operator<<' in 'l_output << std::hex'
note: candidates are: c_Output& operator<<(c_Output&, std::ostream&)

I have stripped away all the file and line information, but it gets the point across. I am obviously getting the type for the rhs of the operator incorrect. What is the correct type and/or correct means of implementing the stream operator as desired?

There is also a complementary c_Input class that has a similar requirement, but adapting the answer for c_Output should be trivial.

The type of std::hex is std::ios_base& (*)(std::ios_base&) . Change your operator signature to:

c_Output& operator<< (c_Output& x_output, std::ios_base& (*x_stream)(std::ios_base&));
operator<< (c_Output& x_output, std::ostream& x_stream)

The only real problem is that std::hex isn't a std::ostream , and with your methods no overloaded << is available for it.

In order to support the usage of the hex modifier, you'll need another friend overload with parameters (c_Output&, ios_base& (*)(ios_base&)) (as hex is a pointer to function taking reference to ios_base returning reference to ios_base ).

At the rate you're going, you'll need to also implement all the other << overloads as well. This is not a trivial task, but is necessary to masquerade as a std::ostream , with or without inheriting from it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM