...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
template<class T> void invoke_swap(T& left, T& right)
noexcept(see below);
The template function boost::core::invoke_swap
allows the values of two variables to be swapped, using argument dependent
lookup to select a specialized swap function if available. If no specialized
swap function is available, std::swap
is used.
The generic std::swap
function requires that the elements
to be swapped are assignable and copy constructible. It is usually implemented
using one copy construction and two assignments (C++11 replaces copy operations
with move) - this is often both unnecessarily restrictive and unnecessarily
slow. In addition, where the generic swap implementation provides only the
basic guarantee, specialized swap functions are often able to provide the
no-throw exception guarantee (and it is considered best practice to do so
where possible[1].
The alternative to using argument dependent lookup in this situation is to
provide a template specialization of std::swap
for every type that requires a specialized swap. Although this is legal C++,
no Boost libraries use this method, whereas many Boost libraries provide
specialized swap functions in their own namespaces.
boost::core::invoke_swap
also supports swapping built-in
arrays. Note that std::swap
originally did not do so, but a request
to add an overload of std::swap
for built-in arrays has been accepted by the C++ Standards Committee[2].
boost::core::invoke_swap
provides the same exception
guarantee as the underlying swap function used, with one exception; for an
array of type T[n]
, where
n >
1
and the underlying swap function
for T
provides the strong
exception guarantee, boost::core::invoke_swap
provides only the basic exception guarantee.
In C++11 and later, boost::core::invoke_swap
propagates the same noexcept
specification as the one specified in the underlying swap function.
Either:
T
must be copy assignable
(since C++11: move assignable)
T
must be copy constructible
(since C++11: move constructible)
Or:
swap(T&, T&)
is available via argument dependent
lookup
Or:
std::swap
exists for T
Or:
T
is a built-in array
of swappable elements
Several older compilers do not support argument dependent lookup. On these
compilers boost::core::invoke_swap
will call std::swap
,
ignoring any specialized swap functions that could be found as a result of
argument dependent lookup.
boost::swap
less specialized than std::swap
, thereby allowing the function
to have the name 'swap' without introducing ambiguity. However, later
the function was renamed to boost::core::invoke_swap
to avoid potential infinite recursion.