Reputation: 5849
I found this question on archived file at joelonsoftware.com http://discuss.joelonsoftware.com/default.asp?joel.3.594503.11
"Hi,
I'm having a particularly slow day and can't get my head round an operator overloading problem. I would like a class to be able to accept data via an insertation operator, i.e:
myClassInstance << std::string("a string") << 4 << 3.4 << std::endl;
Internally, I'd like everything to end up in a stringstream so I can then farm it off to other streams (say std::cout and an ofstream). I have got horribly confused how I can do this without having to write an operator<< overload for every data type, and how an input stream would be created on the first call (myClassInstance << ...).
Any help gratefully received!"
This is exactly what I am trying to do. I have found my way to deal with all types by defining templates and another overloaded method to deal with manipulators like endl defined in ostream class.
UIStream& UIStream ::operator << (const T str)
{
CString cstr(stringify(str).c_str());
theFrame->m_pOutputView->WriteMessage(cstr);
return *this;
}
//for manipulators like std::endl
UIStream& UIStream ::operator <<(ostream& (*m)(ostream&))
{
//stream<<*m;
//CString cstr((*m)(new ostream).c_str());
if(*m==&std::endl);
theFrame->m_pOutputView->WriteMessage("\n");
return (*this);
}
I am still struggling with manipulators that take arguments like hex dec or oct this are defined in ios_base.
Upvotes: 0
Views: 1592
Reputation: 2576
The way I would go is just to include a std::stringstream in MyClass, and overload << to take a MyClass as lhs and anything as RHS.
class MyClass {
public:
template <class T>
MyClass & operator <<(const T & rhs) {
m_stream << rhs;
return *this;
}
private:
std::ostringstream m_stream;
};
edit: I guess it's not exactly what you are looking for. Still could be useful for simpler uses.
Upvotes: 1
Reputation: 52284
The more questions you ask, the more I'm convinced that the correct approach to your problem is writing a new streambuf. There is documentation for that on the net -- explaining it here would be a little too long for me -- and there is a library of boost called iostreams which can help you.
Upvotes: 0
Reputation: 13421
To make your stream work with manipulators that take arguments is not quite as straightforward as when they do not have arguments. The problem is that the maniuplator will be of the form
ImpDefClass manipulator( argument list );
where ImpDefClass
is, as its name suggests, an implementation defined class. For example, on my system, setprecision
is declared as
inline _Setprecision setprecision(int __n);
where _Setprecision
is just a struct
that my implementation defines itself.
The problem therefore is that you can't just write a new stream operator like
UIStream& operator<<( UIStream&, XXX );
because XXX
is the implementation defined class. I'm not sure how to get around that other than define your own manipulators to perform the same tasks or hardwire your code to specific implementations.
Upvotes: 2
Reputation:
Probably an idea to read a good book on the topic. I recommend Standard C++ IOStreams and Locales by Langer and Kreft.
Upvotes: 3