To form a string I use std :: stringstream (I fill it with the operator << ), then I select the resulting string with the method std :: stringstream :: str :

 std::stringstream ss; ss << "foo" << 42 << "bar"; std::string s = ss.str(); 

The original object std :: stringstream is not used further, but it takes up memory. Is it possible to use move-semantics to “take” its string from std :: stringstream (in the example it is not essential, in a real task a line of several hundred megabytes is now typed)?

  • Related question: Move the string out of a std :: ostringstream . There is no good answer on the link, so I would say that there is no normal way to do it. - Fat-Zer
  • Clear the stream. At worst, place the stream in free memory with the new operator and after use delete with the delete operator. Or do you need to do without copying the lines? Then do not take a string from the stream, but work with the ss.str () stream object. - pepsicoca1
  • @ pepsicoca1 Yes, I would not want extra copying. If you work with ss.str () directly, then each such call will create a copy ( ref ). - Vladimir Gamalyan
  • Considering that you have a very specific task (several hundred megabytes), in my opinion, using std::stringstream impractical. - ixSci
  • @ixSci While I see boost karma from alternatives, but I would like to have an ostream interface (a lot of existing code is waiting for it). - Vladimir Gamalyan

2 answers 2

The external specification of the class std::strinstream does not claim that the object std::strinstream is stored inside the object std::strinstream . Therefore, we should not expect that you will be able to “pick up” the contents of std::strinstream in std::string with the help of move semantics.

That is, in the general case, it will not be possible to get rid of the stage of building the object std::string based on the current contents of std::strinstream .

The std::strinstream::str() method returns its result by value. If, when implementing this method, the compiler applies return value optimization (RVO), then the result ss.str() will be constructed directly in your object s . Otherwise, a temporary object of type std::string will be constructed and returned, which you will already take to your s using move semantics. This is probably the only place where move semantics can work.

PS In the light of the above, it is clear that you cannot achieve anything by working with ss.str() "directly." To do this, you still have to construct the result ss.str() . And therein lies the problem, i.e. it saves nothing.

    There were still old string streams not stringstream but strstream. If my memory serves me, then after applying str (), the string inside it was frozen, and the user was given a pointer to the frozen string in the form of char *. If you apply these streams, then there will be no extra copying. True, they seem to be declared obsolete.

    Another option is to write a homemade stream.