0

I am trying to get to the point where essentially MyClass(A) << "hi " << 17 << std::endl; compiles and executes MyClass::finish() method on the accumulated stream. So far, I'm still stuck on the "compiles" part. Here's what I have so far

#include <iostream>
#include <sstream>
#include <string>

enum foo
{
  A,
  B,
  C
};

class MyClass
{

  public:

    MyClass(foo v) : v_(v), oss_()
    {
    }

    MyClass& operator<<(std::ostream &o)
    {
      oss_ << o;
      return *this;
    }

  private:
    foo v_;
    std::ostringstream oss_;
};

int main()
{

  MyClass(A) << "hi " << 17 << std::endl;
  return 0;
}

Am I going down the wrong path?

1
  • what is the expected output? Commented Dec 16, 2024 at 20:45

1 Answer 1

2

Your operator<< is implemented wrong. It should not accept another ostream as input. Instead, it needs to accept all of the types that you want to stream in to your class and forward to your internal ostringstream. You can use a template to simplify that, eg:

template<class T>
MyClass& operator<<(const T &param)
{
  oss_ << param;
  return *this;
}

MyClass& operator<<(std::ostream& (*func)(std::ostream&))
{
  (*func)(oss_);
  return *this;
}

The 1st overload handles data types, and the 2nd overload handles stream manipulators like std::endl, which are implemented as functions.

And then, you can call finish() inside your ~MyClass destructor.

Live Demo

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for the response. The answer makes sense. Unfortunately, I cannot do this because my class is implemented in a shared library and the users of the class are external executables. This means I cannot leverage templates because at compile time of the library, I cannot possibly know all the possible caller types.
Yes, you can, because the template is inline and doesn't need to know all the caller types until it is actually instantiated at the call sites where user code is actually calling the operator.
I started a discussion about this usage in a shared library. Can you please chime in? stackoverflow.com/beta/discussions/79294466/…
@PaulGrinberg you can't split the declaration and definition of a template between h and cpp files. stackoverflow.com/questions/495021/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.