Possible Duplicate:
how to provide a swap function for my class?
Every time I think I understand it, I see something that really confuses me.
If you want to provide an implementation of swap
for your own class, what do you do?
The list of possibilities is:
Define one inside the std
namespace (taking two arguments), which calls #3 below
(some say this is correct; some people say illegal)
Define a static method inside the class, taking two arguments to swap
(makes more sense to me than #4, but I don't get why no one does this), which calls any base-class swap
s as necessary
Define an instance method inside the class, taking one other argument to swap with, which calls any base-class swap
s as necessary
Define an instance method inside the class, taking two other arguments to swap, also here, which calls any base-class swap
s as necessary
Define one in your own namespace (taking two arguments), which calls #3
Something else
My own understanding is that I need #5 and #3, where the caller would then be calling swap
likeusing std::swap; swap(a, b);
,but the fact that no one seems to suggest that combination is really confusing me. And I really don't understand #4 at all, because everyone seems to be using an instance member when in fact the operation is static. I can't tell if my understanding is wrong or a bunch of the answers I see when looking this up.
What's the correct way?
A common pattern I have seen is providing 3 and 5, as per your own understanding.
std::
namespace, which is allowed, but might not be possible in all cases (if your type is a template itself).swap
on other types that hold your type as a member, they will need to qualify the call (void swap( other& l, other& r ) { T::swap( l.t, r.t ); }
)rvalue
s (even in C++03) and is idiomatic in some cases std::vector<int>().swap( v );
to clear the contents of the vector.void swap( other& l, other& r ) { using std::swap; swap( l.t, r.t ); }
without having to know whether the type of other::t
has an specific swap
overload or the one in std::
needs to be used. Forwarding to 3 allows you to provide a single (real) implementation that can be used through ADL and also on temporary objects.