Recently, many questions pop up on how to provide your own swap
function. With C++11, std::swap
will use std::move
and move semantics to swap the given values as fast as possible. This, of course, only works if you provide a move constructor and a move assignment operator (or one that uses pass-by-value).
Now, with that given, is it actually necessary to write your own swap
functions in C++11? I could only think of non-movable types, but then again, the custom swap
s usually work through some kind of "pointer exchange" (aka moving). Maybe with certain reference variables? Hm...
It is a matter of judgment. I will typically let
std::swap
do the job for prototyping code, but for release code write a custom swap. I can usually write a custom swap that is about twice as fast as 1 move construction + 2 move assignments + 1 resourceless destruction. However one may want to wait untilstd::swap
actually proves to be a performance problem before going to the bother.Update for Alf P. Steinbach:
20.2.2 [utility.swap] specifies that
std::swap(T&, T&)
has anoexcept
equivalent to:I.e. if move operations on
T
arenoexcept
, thenstd::swap
onT
isnoexcept
.Note that this spec doesn't require move members. It only requires that construction and assignment from rvalues exists, and if it is
noexcept
, then swap will benoexcept
. E.g.:std::swap<A>
is noexcept, even without move members.Sure, you can implement swap as
But we might have our own class, say
A
, which we can swap more quickly.Which, instead of having to run a constructor and destructor, just swaps the pointers (which may well be implemented as XCHG or something similar).
Of course, the compiler might optimize out the constructor/destructor calls in the first example, but if they have side effects (i.e. calls to new/delete) it may not be smart enough to optimize them away.
Consider the following class that holds a memory-allocated resource (for simplicity, represented by a single integer number):
Then
std::swap
results in deleting null pointer 3 times (both for move assignment operator and unifying assignment operator cases). Compilers might have problem to optimize out such adelete
, see https://godbolt.org/g/E84ud4.Custom
swap
does not call anydelete
and might be therefore more efficient. I guess this is the reason whystd::unique_ptr
provides customstd::swap
specialization.UPDATE
It seems that Intel and Clang compilers are able to optimize out deletion of null pointers, however GCC isn't. See Why GCC doesn't optimize out deletion of null pointers in C++? for details.
UPDATE
It seems that with GCC, we can prevent invoking
delete
operator by rewritingX
as follows:By convention a custom
swap
offers no-throw guarantee. I don't know aboutstd::swap
. My impression of the committee's work on that is that it was all political, so it would not surprise me if they somewhere had definedduck
asbug
, or similar political word-game maneuvers. So I would not rely on any answer here unless it provides a detailed blow by blow quoting from the C++0x to-be-standard, down the smallest detail (so as to be sure nobug
).There might be some types that can be swapped but not moved. I don't know of any non-movable types, so I don't have any examples.