Is there a way to std::move std::string into std::stringstream
Asked Answered
C

2

22

In the c++ reference I do not see a std::stringstream constructor accepting rvalue reference of std::string. Is there any other helper function to move string to stringstream without an overhead or is there a particular reason behind making such limitation?

Cash answered 14/5, 2016 at 17:18 Comment(8)
Probably because std::stringstrream does not store the data as a string internally but inside a stream buffer. So it needs to copy the data from the string into the string buffer. If it used move semantics it would need to take ownership of the string buffer thus need to know how it was allocated (which may not be dynamically allocated see short sting optimization) and know how to set string to a valid state. So allowing move semantics means tightly coupling the string and stringstream class.Acanthopterygian
@LokiAstari: "So allowing move semantics means tightly coupling the string and stringstream class." Yes, God forbid that two classes from the same library be coupled together...Plucky
@NicolBolas: Coupling usually means that there are tradeoffs. Maybe the standard designers did not want to pay those tradeoffs. std::string is pretty crucial to most C++ applications. Do you want to limit optimizations on it just so this one corner case is more efficient? PS I have no intention of defending the IO library you can take that up with the committee (who are smarter than me). Just trying to provide a reasonable explanation for the limitation.Acanthopterygian
@LokiAstari: Your way limits optimizations for cases that you can't even say actually exist. And it's not an either/or kind of thing. The current behavior makes it impossible to allow an implementation to move the string data. str() is a const function; it's not allowed to modify the stringstream's data at all. It would be very easily to create APIs that would permit the moving of string data without requiring it. After moving into the stream, the string would be "valid-but-unspecified". After moving from the stream, the stream would be "valid-but-unspecified."Plucky
@NicolBolas: How is this my fault? It looks like you have a good suggestion for the committee. You should write it up and propose it.Acanthopterygian
@LokiAstari: "Just trying to provide a reasonable explanation for the limitation." The explanation is "nobody on the committee cares about IOStreams". Just look at how many papers are submitted that even consider the impact to iostream types, let alone actually suggest changing them. Filesystem adds path classes, but nobody has even considered allowing fstreams to take them as filenames.Plucky
@LokiAstari yes there is a good change that the limitations is there for a reason, maybe my question was too deep there... There is no simple rationalization for every paragraph of standard...Cash
Since the answer to this question has changed in C++20, you may want to consider changing the accepted answer.Howze
P
11

Since C++20 you can move a string into a stringstream: cppreference


Old answer for pre-C++20:

I do not see a std::stringstream constructor accepting rvalue reference of std::string

That's right. Even the str setter doesn't utilize move semantics, so moving a string into stringstream is not supported (not in the current standard, but hopefully in the next one).

Paranoiac answered 14/5, 2016 at 17:23 Comment(1)
Hopefully there are some good people creating proposals making c++ more straightforward :)Cash
H
11

You'll be able to move a string into a string-stream in C++20.

Move semantics are supported by the constructor:

std::string myString{ "..." };
std::stringstream myStream{ std::move(myString) };

It can also be done after construction by calling str():

std::string myString{ "..." };
std::stringstream myStream;
myStream.str(std::move(myString));
Hornback answered 19/5, 2020 at 14:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.