C++标准是否保证当"rdbuf"的返回值传递给流输出运算符时,缓冲区的附件被打印出来



考虑以下代码片段:

std::stringstream ss;
ss << "hello world!n";
auto a = ss.rdbuf();
std::cout << a; // prints out "hello world!

变量a是指向std::stringbuf类型对象的指针。通过GCC9.4将其传递给流输出操作符<<,输出a所指向的流缓冲区的内容。

我的问题是:这种行为只是std::stringbuf在GCC中实现的方式的意外,还是语言标准保证这将始终有效?

std::basic_stringbuf派生自std::basic_streambuf。Cppreference描述了它的用法:

I/O流对象std::basic_istreamstd::basic_ostream,以及从它们派生的所有对象(std::ofstream,std::stringstream等),完全是根据std::basic_streambuf实现的。

那是什么意思?那么,让我们来看看std::basic_istream::operator<<的重载设置:

basic_ostream& operator<<( std::basic_streambuf<CharT, Traits>* sb );(10)

表现为UnformattedOutputFunction。在构造并检查哨兵对象之后,检查sb是否为空指针。如果是,执行setstate(badbit)并退出。否则,从sb控制的输入序列中提取字符,插入到*this中,直到满足以下条件之一:

  • 文件结束发生在输入序列上;
  • 在输出序列中插入失败(此时要插入的字符未被提取);
  • 异常发生(在这种情况下异常被捕获)。

如果没有插入字符,执行setstate(failbit)。如果在提取时抛出异常,则设置failbit,如果failbitexceptions()中设置,则重新抛出异常。

所以,是的,标准保证std::cout << ss.rdbuf();将具有您观察到的效果。

最新更新