正确实现 std::streambuf::overflow

Correct implementation of std::streambuf::overflow

本文关键字:streambuf overflow std 实现      更新时间:2023-10-16

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

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

实施此案的原因是什么?

好吧,我真的不明白另一种情况,overflow(eof()),也是。尽管明确指定了它,但它似乎并没有在任何地方实际使用。

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

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