3

我想到了 C++ 中的一个小型调试内联函数:

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

这是我想如何使用它的一个例子:

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

但是它不能按我计划的方式工作 - 我希望它仅在详细级别高于或等于传递给函数的调试级别时打印消息,但似乎它每次都会打印,无论调试级别如何,所以数据会保留在 cout 缓冲区中。到目前为止,我认为这个函数不是我最近想到的最好的主意,但我仍然想知道是否有办法清除与 cout、cerr 等相关的缓冲区。是否有可能让这种函数正常工作?

4

4 回答 4

6

使用如上所示的宏,或者像这样:

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;

(使用endl也触发冲洗,无需手动冲洗!)

于 2010-02-03T12:12:49.280 回答
2

我不确定是否可以使用函数/模板来完成。我知道带有宏的代码(您的日志消息和流是分开的):

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

虽然这可行,但我对更好的解决方案感兴趣。请注意,您应该让配置和调试级别决定登录到哪里。

于 2010-02-03T12:05:09.200 回答
2

它将始终打印消息,因为在输入函数体之前评估函数参数。您可以使用宏获得我认为您想要的效果,因为宏参数仅在使用时才被评估:

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

正在使用:

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

如果你很挑剔,你会想把它包装在一个 do/while 循环中——就我个人而言,我从不费心这样做。

于 2010-02-03T12:06:05.737 回答
0

调试级别运行时间是否可配置?
如果不是,您可以使用模板和模板专业化:

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

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

这样,如果您不想输出任何内容,只需像 Konrad Rudolph 建议的那样返回虚拟 ostream。

于 2010-02-03T13:13:28.923 回答