Move semantics for string based stringstream operations

397 views
Skip to first unread message

Curious

unread,
Mar 5, 2017, 8:27:27 PM3/5/17
to ISO C++ Standard - Future Proposals
Stringstreams still don't seem to have any planned changes for enabling moving to and from std::string objects.  Since it seems to be too difficult and out of the way to change std::basic_stringbuf to work seamlessly (in particular when it comes to movability) with std::string objects.  I was thinking that there can be another class that has the same functionality as a std::stringstream but is based on std::string for its internal storage.  The type would be named std::sstream, which is in line with the name of the header that contains the implementation of std::stringstream.  Then deprecate std::stringstream in favor of that, like was previously done with std::strstream.  Or leave std::stringstream in the library if relying on the rdbuf() member function for processing data directly with a stringbuf is common.

Stringstreams are a useful concept to have but most of the time but their move and reference limitations makes it feel like users should use other APIs that do not require expensive copying.  I have even seen people use std::sscanf() and std::sprintf(), just to avoid memory allocations..

The member functions I was hoping to see were the following

/**
 * str() returns a copy of the string contained in the sstream and 
 * remove_str() moves the string into a temporary string which then 
 * is treated as a prvalue in the calling expression and will therefore 
 * be moveable or elidable
 */
std::basic_string<CharT, Traits, Allocator> str() const;
std::basic_string<CharT, Traits, Allocator> remove_str() noexcept;

/**
 * Move and copy assigning a string into a stringstream
 */
void str(const std::basic_string<CharT, Traits, Allocator>& other);
void str(std::basic_string<CharT, Traits, Allocator>&& other);

If another class which allows moving to/from a stringstream seems unnecessary, another option is to make std::stringstream accept one or two more template parameters, one of which is the internal storage type that will be used to store the characters and another which is a traits class that encapsulates how the implementation will interact with the storage object.  And then rdbuf() could just return a pointer to the internally stored storage object (be it a std::basic_streambuf or a std::basic_string),  this would be backwards compatible with other uses of stringstreams since the other two template parameters would default to the ones used right now. 

Daniel Krügler

unread,
Mar 7, 2017, 3:40:26 PM3/7/17
to std-pr...@isocpp.org
There is already work in progress in that area. Please read

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0408r1.pdf

and I would expect that it suggests to provide the functionality you
are expecting above (and more).

- Daniel
Reply all
Reply to author
Forward
0 new messages