简体   繁体   English

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

[英]C++ - Passing std::ostream to a function

I thought of a small debug inline function in C++: 我想到了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. 然而它不能按照我计划的方式工作 - 我希望它只在详细级别高于或等于调试级别传递给函数时打印消息,但它似乎每次打印而不管调试级别如何,因此数据保持不变在cout缓冲区。 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? 到目前为止,我认为这个功能不是我最近的最好的想法,但我仍然想知道是否有办法清除与cout,cerr等相关的缓冲区。是否有可能让这种功能正常工作?

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!) (使用endl也会触发刷新,无需手动刷新!)

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

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. 这样,如果您不想输出任何内容,只需返回像Konrad Rudolph建议的虚拟ostream。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM