正确实现std :: streambuf :: overflow

时间:2013-12-18 20:41:20

标签: c++ iostream

我正在创建一个特殊的std :: streambuf和std :: ostream实现。为此我需要实现std::streambuf::overflow功能。该函数受保护,仅由std::streambuf::sputcstd::streambuf::xsputn调用,并且仅在缓冲区中没有空间时(即pptr() == epptr())。默认行为是返回eof,因此调用该函数代替sputc显然不正确。

尽管如此,std::stringbuf的GNU libc实现和Boost.Format中boost::io::alt_stringbuf的强制实现仍然会检查pptr() < epptr()是否只是追加该字符。在后一种情况下甚至大胆地调用sputc(因此如果缓冲区中仍有空间,则依赖于它不会调用overflow这一事实。)

实施此案的原因是什么?

好的,我也不太了解其他情况,overflow(eof())。它虽然明确指定,但似乎并未在任何地方实际使用。

1 个答案:

答案 0 :(得分:6)

问题似乎是实现检查this->pptr() == this->epptr()的原因:简单的原因是进一步的派生类最终可能会调用protected函数!当缓冲区中有空间时,标准C ++库永远不会调用overflow()。有一段时间我曾经也检查this->pptr() == this->epptr()是否已停止这样做:隐式契约是进一步派生类不做傻事。

提出的另一个问题是:使用参数overflow()调用traits_type::eof()意味着什么?虽然我一直在处理这种情况,但这是另一种情况,它不会发生在标准C ++库中:目的是让overflow()刷新流。也就是说,sync()只会调用this->overflow(traits_type::eof())。在实践中,我发现从sync()调用overflow()可能在将字符存储到缓冲区后更合理(即,sync()可以使用pptr() == epptr() + 1调用,当然,假设{{1}}分配的缓冲区至少有一个字符的空间。)