Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I want to move a stringstream, in the real world application I have some stringstream class data member, which I want to reuse for different string's during operation.

stringstream does not have a copy-assignment or copy constructor, which makes sense. However, according to cppreference.com and cplusplus.com std::stringstream should have a move assignment and swap operation defined. I tried both, and both fail.

Move assignment

#include <string>       // std::string
#include <iostream>     // std::cout
#include <sstream>      // std::stringstream
int main () {
  std::stringstream stream("1234");
  //stream = std::move(std::stringstream("5678"));
  stream.operator=(std::move(std::stringstream("5678")));
  //stream.operator=(std::stringstream("5678"));
  return 0;

source: http://ideone.com/Izyanb

prog.cpp:11:56: error: use of deleted function ‘std::basic_stringstream<char>& std::basic_stringstream<char>::operator=(const std::basic_stringstream<char>&)’
   stream.operator=(std::move(std::stringstream("5678")));

The compiler states that there is no copy assignment for all three statements, which is true. However, I fail to see why it is not using the move-assignment, especially since std::move is supposed to return a rvalue reference. Stringstream should have a move assignment, as shown here: http://en.cppreference.com/w/cpp/io/basic_stringstream/operator%3D

PS: I'm working with c++11, hence rvalue-references are part of the 'world'.

This I found really strange, I copied example code from cplusplus.com and it failed:

// swapping stringstream objects
#include <string>       // std::string
#include <iostream>     // std::cout
#include <sstream>      // std::stringstream
int main () {
  std::stringstream foo;
  std::stringstream bar;
  foo << 100;
  bar << 200;
  foo.swap(bar);
  int val;
  foo >> val; std::cout << "foo: " << val << '\n';
  bar >> val; std::cout << "bar: " << val << '\n';
  return 0;

source: http://ideone.com/NI0xMS cplusplus.com source: http://www.cplusplus.com/reference/sstream/stringstream/swap/

prog.cpp: In function ‘int main()’:
prog.cpp:14:7: error: ‘std::stringstream’ has no member named ‘swap’
   foo.swap(bar);

What am I missing? Why can't I move or swap a stringstream? How should I swap or move a stringstream?

It appears the libstdc++ you are using doesn't have those implemented. Mine (shipped with GCC 4.8.2) doesn't. At least the 4.8 series claimed to be only C++11 language-compliant, with some serious omissions on the standard library. – DanielKO Nov 26, 2014 at 15:23 @SebastianRedl I know, I did so to enforce that that the move assignment was used instead of normal assignment, although It should not make a difference. – Herbert Nov 27, 2014 at 8:52

This is a missing feature on GCC : see bug 54316 , it has been fixed (you can thank Jonathan Wakely) for the next versions (gcc 5)

Clang with libc++ compiles this code :

int main () {
  std::stringstream stream("1234");
  std::stringstream stream2 = std::move(std::stringstream("5678"));
  return 0;

Live demo

And it also compiles the example with std::stringstream::swap

for the time being a common workaround is to put the non movable object (in this case a stringstream) in a unique_ptr, and move that one. – dau_sama Nov 26, 2014 at 15:22 I'm not contributing to gcc. This is all Jonathan (and whoever else Jonathan says contributed). – Howard Hinnant Nov 26, 2014 at 16:57 Unfortunately, the unique_ptr<> workaround changes the API, so that even users using conforming compilers must use it. – Adi Shavit Oct 18, 2016 at 14:00
    #include <string>       // std::string
    #include <iostream>     // std::cout
    #include <sstream>      // std::stringstream
    int main () {
      std::stringstream ss("1234");
      ss.clear();
      ss.str("5678");
      int val;
      ss >> val; std::cout << "val: " << val << '\n';
      return 0;

It's a clean work around that does not require one to refactor code, except for the localized section where the swap is changed to a clear() and str().

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.