我正在使用的软件库向写入了大量调试输出std::cerr
,但是如果我告诉输出安静,则将该输出重定向到空流。这是简化main.cpp
的代码,显示了代码如何尝试实现此目的:
#include <iostream>
#include <fstream>
#include <cassert>
// The stream that debug output is sent to. By default
// this points to std::cerr.
std::ostream* debugStream(&std::cerr);
// Throughout the library's codebase this function is called
// to get the stream that debug output should be sent to.
std::ostream& DebugStream()
{
return *debugStream;
}
// Null stream. This file stream will never be opened and acts
// as a null stream for DebugStream().
std::ofstream nullStream;
// Redirects debug output to the null stream
void BeQuiet()
{
debugStream = &nullStream;
}
int main(int argc, char** argv)
{
DebugStream() << "foo" << std::endl;
BeQuiet();
DebugStream() << "bar" << std::endl;
assert(debugStream->good());
return 0;
}
当您运行该程序时,您会注意到字符串“ bar”已正确发送到空流。但是,我注意到断言失败。这是我应该关注的事情吗?还是这仅仅是库开发人员选择的方法的一点点丑陋细节?
如果您愿意,欢迎提供更好的替代方法的建议。一些约束:
/dev/null
不是有效的解决方案,因为它在Windows上不起作用不必担心流不存在good()
!由于输出运算符实际上不会在故障模式下对流进行任何操作,因此未格式化所记录的不同实体,即,与替代方法相比,代码的运行速度更快。
请注意,您实际上并不需要第二个流来禁用输出:
假设所有输出运算符行为良好,则可以设置std::ios_base::failbit
:
debugStream().setstate(std::ios_base::failbit);
如果存在行为不正确的输出,即使不是,good()
也可以写入流,则可以将其流缓冲区设置为null:
debugStream()。rdbuf(nullptr);
如果您确实希望流保持good()
状态,则可以安装仅消耗字符的流缓冲区。但是请注意,您要为该流缓冲区提供一个缓冲区,因为overflow()
为每个流调用都char
相当昂贵:
struct nullbuf
: std::streambuf {
char buf[256];
int overflow(int c) {
this->setp(this->buf, this->buf + 256);
return std::char_traits<char>::not_eof(c);
}
};
...
nullbuf sbuf;
debugStream().rdbuf(&sbuf);
...
debugStream().rdbuf(0);
必须重置流的流缓冲区,因为的析构函数std::ostream
将刷新strsm缓冲区(即,它调用pubsync()
)。对已损坏的流缓冲区执行此操作将无效。
就个人而言,我会选择设置std::ios_base::failbit
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句