C++:std::istream read及其对std::streambuf underflow的调用

C++: std::istream read and its calls to std::streambuf underflow

本文关键字:std streambuf underflow 调用 istream read C++      更新时间:2023-10-16

下面的代码只是测试在std::stringbuf上使用std::istream read时调用underflow的频率。

#include <iostream>
#include <vector>
#include <sstream>
class TestStringBuf : 
public std::stringbuf
{
public:
    int_type underflow()
    {
        std::cout<<"TestStringBuf underflow"<<std::endl;
        return std::stringbuf::underflow();
    }
};
int main(int argc, const char * argv[])
{
    TestStringBuf buf;
    std::iostream stream(&buf);
    stream << "tesr";
    std::vector<char> data(4);
    stream.read(&data[0], 4);
    for(int i=0; i<data.size(); ++i)
        std::cout<<data[i];
    std::cout<<std::endl;
    return 0;
}

输出为:

TestStringBuf underflow
TestStringBuf underflow
test

我希望下溢只被调用一次,因为我准确地读取了 get 区域中存在的字节数,那么为什么它应该再次下溢呢?这是预期的行为吗?我问是因为我的自定义underflow方法可能会长时间阻止读取新数据,因此在这种情况下,第二次调用underflow不是很可取。

我在Osx上使用clang 3.1libc ++

谢谢!

更新:

我刚刚做了一个完全独立的测试,在我看来,这在libc++实现中是一个奇怪的问题,因为libstd ++不会发生这种情况。 有人可以用其他实现来测试吗? 这是一个错误还是只是一个实现差异(对我来说感觉很错误)。我更新了上面的代码,以便您可以将其复制并粘贴到任何主.cpp中。

更新2:

毕竟这是libc ++中的一个错误,请参阅:http://llvm.org/bugs/show_bug.cgi?id=13113 。如果你自己编译libc ++,这个错误应该会消失,我会尽快尝试。

C++标准明确允许 std::basic_stringbuf 的实现将字符序列存储在 std::basic_string 中,而不是使用 std::basic_streambuf 的内部缓冲区。