Why doesn't `std::stringstream::stringstream(std::string&&)` exist?

I was hoping stringstream has a constructor that steals its initial content from a string&&. Do such inter-species "move constructors" generally not exist in the STL? If not, why not?


Solution 1:

There's history, which is disappointing. But also a future that looks bright.

When move semantics went into C++11, it was huge, controversial, and overwhelming. I wanted to be able to move strings into and out of stringstream. However the politics at the time demanded that the internal store did not have to be a basic_string<charT>. For example the internal store could be a vector. And there was no ability to control things with an allocator. In any event, the need was recognized in the C++11 time frame, but it was just a bridge too far.

Fortunately Peter Sommerlad has picked up the slack with P0408. This proposal adds the functionality you seek, hopefully for C++20, but that is not certain yet. It has successfully passed through the LEWG, and is on the LWG's desk right now. They did not get to it this month in Rapperswil, purely because of an overloaded schedule. I am hopeful that it will pass through the LWG, and the full committee vote. It certainly will have my vote.

Solution 2:

Why doesn't std::stringstream::stringstream(std::string&&) exist?

This is due to std::stringstream's internal buffer, rdbuf.

rdbuf, (type std::string_buf), doesn't support non-copy access as per the motivation in proposal, p0408r4:

... there is no non-copying access to the internal buffer of a basic_stringbuf which makes at least the obtaining of the output results from an ostringstream inefficient, because a copy is always made

However, there's already a plan to support std::string move in stringsteam's constructor:

explicit basic_ostringstream(
   basic_string<charT, traits, Allocator>&& str,
   ios_base::openmode which = ios_base::out,
   const Allocator& a = Allocator());

AND move str()

template<class SAlloc = Allocator>
void str(basic_string<charT, traits, SAlloc>&& s);