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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:15:09  来源:igfitidea点击:

Is there a null std::ostream implementation in C++ or libraries?

c++nullostream

提问by paperjam

I'm looking for a std::ostreamimplementation 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 streambufwhich 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 istreamor ostreamas 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 badbiton 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 的情况下克服性能问题:

##代码##