views:

1244

answers:

3

I've a working logger class, which outputs some text into a richtextbox (Win32, C++). Problem is, i always end up using it like this:

stringstream ss;  
ss << someInt << someString;  
debugLogger.log(ss.str());

instead, it would be much more convenient to use it like a stream as in:

debugLogger << someInt << someString;

Is there a better way than forwarding everything to an internal stringstream instance? If'd do this, when would i need to flush?

+2  A: 

In the Logger class, override the << operator.

Click Here to know how to implement the << operator.

You can also avoid the logging statements inside the code using Aspect Oriented programming.

Vinay
+17  A: 

You need to implement operator << appropriately for your class. The general pattern looks like this:

template <typename T>
logger& operator <<(logger& log, T const& value) {
    log.your_stringstream << value;
    return log;
}

Notice that this deals with (non-const) references since the operation modifies your logger. Also notice that you need to return the log parameter in order for chaining to work:

log << 1 << 2 << endl;
// is the same as:
((log << 1) << 2) << endl;

If the innermost operation didn't return the current log instance, all other operations would either fail at compile-time (wrong method signature) or would be swallowed at run-time.

Konrad Rudolph
How would i handle the "flush issue", i.e. at one point i need to send everything down to my richtextbox. Should i test the incoming value for "endline"?
jn_
This is a separate question but the answer is easy: instead of using '\n', use endl! This flushes the stream automatically. However, in order to wire a TextBox up to a stream you basically need to implement your own stream buffer (look at the rdbuf method).
Konrad Rudolph
Or add your own manipulator type that mimics endl/ends, with an overload of the << operator to detect it.
Kylotan
+6  A: 

Overloading the insertion operator<< is not the way to go. You will have to add overloads for all the endl or any other user defined functions.

The way to go is to define your own streambuf, and to bind it into a stream. Then, you just have to use the stream.

Here are a few simple examples:

Luc Hermitte