C ++ - 将std :: ostream传递给函数

时间:2010-02-03 11:50:46

标签: c++ iostream ostream

我想到了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 个答案:

答案 0 :(得分: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也会触发刷新,无需手动刷新!)

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:2)

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

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

使用中:

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

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

答案 3 :(得分:0)

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

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

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

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