A std::basic_stringbuf
is derived from a std::basic_streambuf. Cppreference describes its use:
The I/O stream objects std::basic_istream
and std::basic_ostream
, as well as all objects derived from them (std::ofstream
, std::stringstream
, etc), are implemented entirely in terms of std::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 if sb
is a null pointer. If it is, executes setstate(badbit)
and exits. Otherwise, extracts characters from the input sequence controlled by sb
and inserts them into *this
until 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, sets failbit
and, if failbit
is set in exceptions()
, rethrows the exception.
So, yes, it's guaranteed by the standard that std::cout << ss.rdbuf();
will have the effect you observed.