C++ 或库中是否有空 std::ostream 实现?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8243743/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a null std::ostream implementation in C++ or libraries?
提问by paperjam
I'm looking for a std::ostream
implementation that acts like /dev/null
. It would just ignore anything that is streamed to it. Does such a thing exist in the standard libraries or Boost? Or do I have to roll my own?
我正在寻找一种std::ostream
类似于/dev/null
. 它只会忽略流式传输到它的任何内容。标准库或Boost中是否存在这样的东西?还是我必须自己滚动?
采纳答案by Ylisar
If you have boost, then there's a null ostream & istream implementation available in boost/iostreams/device/null.hpp . The gist of it:
如果你有 boost,那么 boost/iostreams/device/null.hpp 中有一个 null ostream & istream 实现可用。它的要点:
#include "boost/iostreams/stream.hpp"
#include "boost/iostreams/device/null.hpp"
...
boost::iostreams::stream< boost::iostreams::null_sink > nullOstream( ( boost::iostreams::null_sink() ) );
...
回答by James Kanze
The simplest solution is just to use an unopened std::ofstream
. This
will result in an error state in the stream, but most outputters won't
check this; the usual idiom is to leave the check to the end, after the
close (which would put it in code you wrote, where you know that the
stream should be invalid).
最简单的解决方案是使用未打开的std::ofstream
. 这将导致流中出现错误状态,但大多数输出器不会检查它;通常的习惯用法是在关闭之后将检查留在最后(这会将它放在您编写的代码中,您知道流应该无效)。
Otherwise, it's pretty straight forward to implement: just create a
streambuf
which contains a small buffer, and sets it up in overflow
(always returning success). Note that this will be slower than the
unopened file, however; the various >>
operators will still to all of
the conversion (which they don't do if the stream has an error state).
否则,实现起来非常简单:只需创建一个
streambuf
包含小缓冲区的对象,并将其设置overflow
(总是返回成功)。请注意,这将比未打开的文件慢;各种>>
运算符仍将进行所有转换(如果流具有错误状态,它们不会这样做)。
EDIT:
编辑:
class NulStreambuf : public std::streambuf
{
char dummyBuffer[ 64 ];
protected:
virtual int overflow( int c )
{
setp( dummyBuffer, dummyBuffer + sizeof( dummyBuffer ) );
return (c == traits_type::eof()) ? 'class NulOStream : private NulStreambuf, public std::ostream
{
public:
NulOStream() : std::ostream( this ) {}
NulStreambuf* rdbuf() const { return this; }
};
' : c;
}
};
It's usual to provide a convenience class derived from istream
or ostream
as well, which will contain an instance of this
buffer which it uses. Something along the lines of:
通常提供一个从istream
或派生的便利类ostream
,它将包含它使用的这个缓冲区的一个实例。类似的东西:
#include <iostream>
int main() {
std::cout << "a\n";
std::cout.setstate(std::ios_base::badbit);
std::cout << "b\n";
std::cout.clear();
std::cout << "c\n";
}
Or you can just use an std::ostream
, passing the address of
the streambuf to it.
或者您可以只使用std::ostream
,将流缓冲的地址传递给它。
回答by Maxim Egorushkin
If you set badbit
on a stream it won't output anything:
如果您badbit
在流上设置,它将不会输出任何内容:
a
c
Outputs:
输出:
a) /dev/null : 30 seconds
b) NullStream: 50 seconds
c) badbit : 16 seconds (the winner in speed, but cannot test for errors!)
d) boost : 25 seconds (the ultimate winner)
回答by Grzegorz
I know this is very old thread, but I would like to add this to anyone who is looking for the same solution without boost and the fastest one.
我知道这是一个非常古老的线程,但我想将此添加到任何正在寻找没有提升和最快解决方案的相同解决方案的人。
I combined three different proposals above and one writing directly to /dev/null (so it involves kernel.)
我结合了上面三个不同的建议,一个直接写入 /dev/null (所以它涉及内核。)
Surprisingly the NullStream that got the most votes performed the worst.
令人惊讶的是,获得最多选票的 NullStream 表现最差。
Here are results for 100,000,000 writes:
以下是 100,000,000 次写入的结果:
#include <iostream>
#include <fstream>
#include <time.h>
#include <boost/iostreams/stream.hpp>
class NullStream : public std::ostream {
class NullBuffer : public std::streambuf {
public:
int overflow( int c ) { return c; }
} m_nb;
public:
NullStream() : std::ostream( &m_nb ) {}
};
int test( std::ostream& ofs, const char* who ) {
const time_t t = time(NULL);
for ( int i = 0 ; i < 1000000000 ; i++ )
ofs << "Say the same" ;
std::cout << who << ": " << time(NULL) - t << std::endl;
}
void devnull() {
std::ofstream ofs;
ofs.open( "/dev/null", std::ofstream::out | std::ofstream::app );
test(ofs, __FUNCTION__);
ofs.close();
}
void nullstream() {
NullStream ofs;
test(ofs, __FUNCTION__);
}
void badbit() {
std::ofstream ofs;
ofs.setstate(std::ios_base::badbit);
test(ofs, __FUNCTION__);
}
void boostnull() {
boost::iostreams::stream< boost::iostreams::null_sink > nullOstream( ( boost::iostreams::null_sink() ) );
test(nullOstream, __FUNCTION__);
}
int main() {
devnull();
nullstream();
badbit();
boostnull();
return 0;
}
Here is the test code
这是测试代码
struct NullStream // only subclass std::stream if you must
{
template<typename T>
NullStream& operator<<(T const&) { return *this; }
};
NullStream TheNullStream; // There's your global instance
EDIT
编辑
The fastest solution - where we use badbit - has a downside. If the program checks if the output is successfully written - and I have no idea why the program should not do that - then it will fail because of this badbit. Therefore, the runner up - boost- is the winner.
最快的解决方案 - 我们使用 badbit - 有一个缺点。如果程序检查输出是否成功写入 - 我不知道为什么程序不应该这样做 - 那么它会因为这个坏位而失败。因此,亚军 -助推- 是赢家。
回答by user5406764
#include <iostream>
class NullStream : public std::ostream {
public:
NullStream() : std::ostream(nullptr) {}
NullStream(const NullStream &) : std::ostream(nullptr) {}
};
template <class T>
const NullStream &operator<<(NullStream &&os, const T &value) {
return os;
}
int main() {
auto null = NullStream();
std::cerr << "a" << std::endl;
null << "b" << std::endl;
std::cerr << "c" << std::endl;
}
回答by Vlad Faust
Following the @user5406764's answer, it is possible to skip any actual operations by overloading the global <<
operator. The solution should be cross-platform and the fastest one.
按照@user5406764 的回答,可以通过重载全局<<
运算符来跳过任何实际操作。解决方案应该是跨平台的并且是最快的。
a
c
Output:
输出:
#include <fstream>
std::ostream* out = &std::cout;
std::ostream* nullstream() {
static std::ofstream os;
if (!os.is_open())
os.open("/dev/null", std::ofstream::out | std::ofstream::app);
return &os;
}
int main() {
*out << "Normal output\n";
out = nullstream();
*out << "Will not visible\n";
out = &std::cout;
*out << "Back again\n";
return 0;
}
回答by user1317490
As for me the simplest way would be:
至于我,最简单的方法是:
std::ostream* nullstream() {
static std::ofstream os;
static bool flag_set = false;
if (!flag_set) {
os.setstate(std::ios_base::badbit);
flag_set = true;
}
return &os;
}
Or use 'badbit' flag instead of '/dev/null' in 'nullstream' function as described above.
或者如上所述在“nullstream”函数中使用“badbit”标志而不是“/dev/null”。
#include <ostream>
class dev0_buffer : public std::streambuf
{
//called usually for n-characters
std::streamsize xsputn (const char* s, std::streamsize n) override { return n; }
//may not required due it's not called anymore
int overflow (int c) override { return c; }
} nirwana;
class dev0_stream : public std::ostream
{
public:
dev0_stream(): std::ostream(&nirwana){}
};
回答by Karsten
May this solution overcomes the performance issue without using boost:
愿此解决方案在不使用 boost 的情况下克服性能问题:
##代码##