我正在创建一个特殊的std :: streambuf和std :: ostream实现。为此我需要实现std::streambuf::overflow
功能。该函数受保护,仅由std::streambuf::sputc
和std::streambuf::xsputn
调用,并且仅在缓冲区中没有空间时(即pptr() == epptr()
)。默认行为是返回eof
,因此调用该函数代替sputc
显然不正确。
尽管如此,std::stringbuf
的GNU libc实现和Boost.Format中boost::io::alt_stringbuf
的强制实现仍然会检查pptr() < epptr()
是否只是追加该字符。在后一种情况下甚至大胆地调用sputc
(因此如果缓冲区中仍有空间,则依赖于它不会调用overflow
这一事实。)
实施此案的原因是什么?
好的,我也不太了解其他情况,overflow(eof())
。它虽然明确指定,但似乎并未在任何地方实际使用。
答案 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}}分配的缓冲区至少有一个字符的空间。)