iter_swap() versus swap() -- what's the difference?
The standard itself has very few mentions of iter_swap
:
- It should have the effect of
swap(*a, *b)
, although there is no stipulation that it must be implemented that way. - The dereferenced values
*a
and*b
must be "swappable", which implies thatswap(*a, *b)
must be valid, and thus the dereferenced types must be identical, although the iterator types do not have to be. -
iter_swap
is required to be used in the implementation ofstd::reverse
. No such requirement is placed on any other algorithm, so this seems to be an oddity.
To borrow what sehe had found from the SGI docs:
Strictly speaking,
iter_swap
is redundant. It exists only for technical reasons: in some circumstances, some compilers have difficulty performing the type deduction required to interpretswap(*a, *b)
.
All of these seem to suggest that it is an artifact of the past.
This seems to be one of those scenarios in which the internet produces a host of conflicting information.
cplusplus.com says that
iter_swap
is identical toswap
and, by that logic, MSDN would be correct in saying that one ought to simply stick toswap
.cppreference.com tells us that calling
swap
is merely a possible implementation foriter_swap
, opening the door for possible optimisations initer_swap
for certain specialisations, as long as the function's constant complexity guarantee is upheld.
The standard, under [C++11: 25.3.3/5]
, says only that iter_swap(a,b)
has the result swap(*a,*b)
(and requires that "a
and b
shall be dereferenceable", and that "*a
shall be swappable with *b
") which would at first glance correlate with MSDN's interpretation.
However, I believe Microsoft have neglected to consider the as-if rule, which should allow an implementation to make iter_swap
faster than swap
in certain cases (e.g. elements of a linked list).
I would therefore trust that the comp.std.c++
quote is the more technically accurate of the two.
That being said, there is a fairly strict limit on the optimisation that may be performed. Consider, for example, an implementation of iter_swap
over linked list elements that simply re-links nodes rather than physically swapping the element values — this is not a valid implementation, because the requirement that iter_swap
's observable behaviour match swap
's is violated.
I would therefore suggest that in practice there can be little if any benefit to preferring iter_swap
over swap
, and I'd recommend sticking to the latter for simplicity and consistency. C++11 move semantics ought to make swap
a cinch in many cases anyway.