The following segment demonstrates my issue: (compilation error on GCC)
stringstream ss;
string s;
ss << "Hello";
// This fails:
// s.swap(ss.str());
// This works:
ss.str().swap(s);
My error:
constSwap.cc:14: error: no matching function for call to 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >::swap(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
basic_string.tcc:496: note: candidates are: void std::basic_string<_CharT, _Traits, _Alloc>::swap(std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
While I understand that str() in stringstream returns a temporary, it does not make sense and was not immediately apparent that I should have been calling the swap on the temporary with the local variable as parameter instead of my first instinct.
Obviously straight assignment works better, and newer C++ standards have move semantics which is perfect, but these are not available for my implementation.
Visual Studio does not give this problem due to it being relaxed about the C++ standard. I kinda already understand the whole const reference to a temporary thing (which I assume is the reason for my compilation errors).
My question: Can anyone explain to me if this is the only solution, and perhaps explain to me the how to think about this in future so I can spot and work around similar issues?
(If no-one has any great insights I'm at least posting this here for people with similar issues)
After having used the swap-with-temporary idiom enough times, with lines like
std::vector<int>().swap(v); // clear and minimize capacity
or
std::vector<int>(v).swap(v); // shrink to fit
this does not seem so out of place. It's normal to call swap as a member function of a temporary object. Of course, it's not so idiomatic to use swap to fill in a default-constructed string instead of using a copy constructor, as already mentioned.