开发者

C++ - Passing std::ostream to a function

I thought of a small 开发者_StackOverflow中文版debug inline function in C++:

void inline debug( int debug_level, ostream& out ) {
    if ( debug_level <= verbosity ) {
        out.flush();
    }
    else {
        ostream tmp;
        tmp << out;
    }
}

This is an example of how I wanted to use it:

_debug( 7, cout << "Something something" << someint << endl );

However it does not work in the way I planned - I wanted it to print the message only if the verbosity level is higher or equal then the debug level passed to function, but it seems it prints everytime regardless of the debug level, so data stays in the cout buffer. By now I think this function's not the best idea I've had lately, but still I want to know if there's a way to clear the buffer associated with cout, cerr etc. Is it possible to get this kind of function to work properly?


Either using a macro as shown above, or like this:

struct nullstream : ostream {
    nullstream() : ostream(0) { }
};

ostream& dout(int debug_level, ostream& out = cerr) {
    static nullstream dummy;
    return debug_level <= verbosity ? dummy : out;
}

// …

dout(level) << "foo" << endl;
dout(level, cout) << "IMPORTANT" << endl;

(Using endl also triggers flushing, no need to flush manually!)


I'm not sure whether it can be done with functions/templates. I know code with macro's (your log-message and stream is separated):

#define LOG(svrty, out, msg)\
do {\
  if (svrty >= debug_level) out << msg;\
} while(0)

Although this works, I am interested in better solutions. Remark that you should let the configuration and debug-level decide where to log to.


It will always print the message, because function parameters are evaluated before the body of the function is entered. You can get the effect I think you want with a macro, as macro parameters are only evaluated when they are used:

#define DOUT( level, expr )   \
   if ( level >= verbosity )  {     \
      expr << endl;          \
  }

In use:

 DOUT( 42, cout << "The value is " << something );

If you are picky, you will want to wrap this in a do/while loop - personally, I never bother doing so.


Is the debug level run time configureable?
If not you may use templates and template specialization:

template <int DebugLevel, int Verbosity>
ostream &debug(ostream &out);

template<>
ostream &debug<7, 5>(ostream &out) { /* do stuff */ }

That way if you don't want to output anything, just return the dummy ostream like Konrad Rudolph suggested.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜