为什么 boost::iostream::filtering_ostream 使用 boost::iostreams::zlib_compressor 需要销毁才能写入接收器?

Why boost::iostream::filtering_ostream using boost::iostreams::zlib_compressor needs to be destroyed for the sink to be written?

今天花了很多时间调试问题后,我注意到 boost::iostream::filtering_ostream 需要销毁才能写入接收器。

测试代码:

#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/zlib.hpp>

#include <sstream>

struct ZlibOstream : boost::iostreams::filtering_ostream
{
    ZlibOstream(std::ostream& os)
    {
        boost::iostreams::filtering_ostream::push(boost::iostreams::zlib_compressor{});
        boost::iostreams::filtering_ostream::push(os);
    }
};

int main()
{   
    std::ostringstream oss;

    #ifdef HAS_SCOPE
    {
    #endif

    ZlibOstream zlibOstream{oss};

    zlibOstream << "This is a test string.\n";

    #ifdef HAS_SCOPE
    }
    #endif

    return (oss.tellp() == 0);
}

调用 flush() 没有用,当我删除 zlib_compressor.

时我不需要这样做

大肠杆菌的结果:https://coliru.stacked-crooked.com/a/7cd166d2d820e838

这种行为背后的原因是什么?

这实际上与这个问题有关:

Flushing a boost::iostreams::zlib_compressor. How to obtain a "sync flush"?

您需要调用 boost::iostreams::zlib_compressor::close 才能进行刷新。

您可以通过在 boost::iostream::filtering_ostream 上调用 pop()reset() 来实现。

注意,pop() 顾名思义弹出链中的最后一个过滤器并 reset() 完全清除链,这样 filtering_ostream 之后将无法使用。

示例:

#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/zlib.hpp>

#include <sstream>

struct ZlibOstream : boost::iostreams::filtering_ostream
{
    ZlibOstream(std::ostream& os)
    {
        boost::iostreams::filtering_ostream::push(boost::iostreams::zlib_compressor{});
        boost::iostreams::filtering_ostream::push(os);
    }
};

int main()
{   
    std::ostringstream oss;

    ZlibOstream zlibOstream{oss};

    zlibOstream << "This is a test string.\n";

    zlibOstream.reset(); // needed if you want to write to oss

    return oss.tellp();
}