Consider the following code snippet:
std::stringstream ss;
ss << "hello world!\n";
auto a = ss.rdbuf();
std::cout << a; // prints out "hello world!
The variable a is a pointer to an object of the type std::stringbuf. When it is passed to the stream output operator <<, with GCC9.4, the content of the stream buffer pointed by a gets printed out.
My question is: is this behavior just an accident from the way std::stringbuf is implemented in GCC, or does the language standard guarantee this will always work?
CodePudding user response:
A std::basic_stringbuf is derived from a std::basic_streambuf. Cppreference describes its use:
The I/O stream objects
std::basic_istreamandstd::basic_ostream, as well as all objects derived from them (std::ofstream,std::stringstream, etc), are implemented entirely in terms ofstd::basic_streambuf.
What does that mean? Well, let's take a look at the overload set for std::basic_istream::operator<< here:
basic_ostream& operator<<( std::basic_streambuf<CharT, Traits>* sb );(10)
Behaves as an
UnformattedOutputFunction. After constructing and checking the sentry object, checks ifsbis a null pointer. If it is, executessetstate(badbit)and exits. Otherwise, extracts characters from the input sequence controlled bysband inserts them into*thisuntil one of the following conditions are met:
- end-of-file occurs on the input sequence;
- inserting in the output sequence fails (in which case the character to be inserted is not extracted);
- an exception occurs (in which case the exception is caught).
If no characters were inserted, executes
setstate(failbit). If an exception was thrown while extracting, setsfailbitand, iffailbitis set inexceptions(), rethrows the exception.
So, yes, it's guaranteed by the standard that std::cout << ss.rdbuf(); will have the effect you observed.
