5

STL classes define swap() method as void swap(A&), taking an l-value reference. See for example std::vector::swap, or the question Is it necessary to use std::move when swapping two objects?

Such definition means we cannot swap with r-values, since r-value won't bind to However, I see no harm in swapping with r-values. Construct it, steal from it, place some guts in it, destroy it. Done. We can add another overload void swap(A&&) to make it happen.

I see only one reason why we do not have this overload out of the box. Because instead of writing

v.swap(rvalue);

It is better to write

v = rvalue;

And instead of swapping we will trigger move-assignment, which is even more efficient. Am I right that this reason is valid? Is this the only reason?

3
  • 5
    Why not write rvalue.swap(v)? Commented Jan 24, 2016 at 18:33
  • @KerrekSB Right, if I can write rvalue.swap(v), why I cannot write the opposite? swap operation is commutative, so I'd expect it to be accessible in both ways. Commented Jan 25, 2016 at 6:52
  • 1
    Member functions aren't really commutative anyway. Commented Jan 25, 2016 at 11:30

3 Answers 3

4

One of the original move papers actually specified this for the containers:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1858.html#23.2%20-%20Sequences

And later propagated to shared_ptr and function:

http://cplusplus.github.io/LWG/lwg-defects.html#743

http://cplusplus.github.io/LWG/lwg-defects.html#770

Swapping with rvalue arguments fell out of favor with LWG 884:

http://cplusplus.github.io/LWG/lwg-defects.html#884

And N2844 subsequently removed all rvalue swaps:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2844.html

I'm not positive this was a good move. However with the more modern shrink_to_fit() way of reducing memory, I'm not positive it matters, since that was the main use case of swapping with rvalues.

Sign up to request clarification or add additional context in comments.

Comments

2

You've more or less answered your own question.

We needed

  v.swap(rvalue);

in the bleak dark-ages leading up to C++11. Since then, we can explicitly grab a hold of rvalues to do as we please.

Allowing swap to take rvalues would be taking a step backwards

Comments

2

The point of "moving" is that you don't care about the state of the source once you've moved from it. This is totally different with swap, where both states are well-defined afterwards.

IOW, A::swap(A&& rhs) at the same time does and does not guarantee what state rhs will be in afterwards.

3 Comments

Disagree. A::swap(A&& rhs) strictly defines the state of rhs after the call. The fact that rhs is automatically destroyed at the end of the statement, does not matter here.
@Mikhail: Why would A::swap(A&& rhs) strictly define the state of a moved-from variable? You seem to be introducing one special member function that is exempt from the rule that moved-from variables are left in an unspecified state.
Ok, agree. I forgot we cannot rely on the fact that e.g. a moved-from vector is empty.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.