Topic: Move semantics in stringstream


Author: Jason McKesson<jmckesson@gmail.com>
Date: Sun, 26 Feb 2012 08:04:57 -0800 (PST)
Raw View
strstream is very useful. In C++98/03, it was useful because it avoided
unneeded copies of strings. For example:

std::ostringstream out_data;
out_data<<  ...;
std::string my_data = out_data.str();

The last line causes a copy, rather unnecessarily, since this function
is now done with out_data.

By contrast, we can do this with strstream:

char buffer[1000];
std::ostrstream out_data(buffer, 1000);
out_data<<  ...;

This requires no copying of the data. Obviously the string is a char*
rather than a std::string, but we at least have the data without a copy.

In C++11, we have move semantics. So the copying is completely
unnecessary from a language point of view. Sadly, the API was not
properly updated to match.

What we need is for std::stringbuf and the corresponding functions in
the stringstream classes to be able to have a string moved into them.
Also, they should be able to have their contents removed without a copy.
So it would look something like this:

std::stringstream out_data{std::move(some_string)};
out_data<<  ...;
std::string my_data = out_data.move_str();

Where move_str() will actually steal the string from the stream. No
string data is ever copied here. move_str should properly invalidate the
stream, as if the user had moved from the stream itself.

The current constructor of std::stringbuf, and the associated
stringstream classes, take a `const&` to a basic_string. They should
take their string argument by value (thus copying when movement is not
allowed) and simply move it to where it needs to go. If that is not
possible due to backwards compatibility issues, then it can take an
r-value reference instead of a value.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]




Author: =?ISO-8859-1?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Sun, 4 Mar 2012 14:23:21 -0800 (PST)
Raw View
Am 26.02.2012 17:04, schrieb Jason McKesson:
[..]
>
> In C++11, we have move semantics. So the copying is completely
> unnecessary from a language point of view. Sadly, the API was not
> properly updated to match.
>
> What we need is for std::stringbuf and the corresponding functions in
> the stringstream classes to be able to have a string moved into them.
> Also, they should be able to have their contents removed without a copy.


I agree.

> So it would look something like this:
>
> std::stringstream out_data{std::move(some_string)};


Presumably this is a function that implementors could easy provide
(and probably will).

> out_data<< ...;
> std::string my_data = out_data.move_str();


I generally agree with the usefulness of that.

> Where move_str() will actually steal the string from the stream. No
> string data is ever copied here. move_str should properly invalidate the
> stream, as if the user had moved from the stream itself.


My initial reaction was that this may be too strong (because the
function name may indicate a less harmful operation), but after some
further reflections I tend to agree.

> The current constructor of std::stringbuf, and the associated
> stringstream classes, take a `const&` to a basic_string. They should
> take their string argument by value (thus copying when movement is not
> allowed) and simply move it to where it needs to go. If that is not
> possible due to backwards compatibility issues, then it can take an
> r-value reference instead of a value.


There is no reason to enforce implementations to break their ABI. IMO
adding constructors that accept a basic_string<>&& should suffice. We
may want the same for the str() setter function. There are similar
examples in the standard that follow this signature "strategy", e.g.
the container adaptors.

Related to that one could argue that basic_regex should provide
similar string-based move operations.

Greetings from Bremen,

Daniel Kr   gler




--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]