std::swap() algorithm
- since C++20
- since C++11
- until C++11
// (1)
template< class T >
constexpr void swap( T& a, T& b ) noexcept(/* see below */);
// (2)
template< class T2, std::size_t N >
constexpr void swap( T2 (&a)[N], T2 (&b)[N] ) noexcept(/* see below */);
// (1)
template< class T >
void swap( T& a, T& b ) noexcept(/* see below */);
// (2)
template< class T2, std::size_t N >
void swap( T2 (&a)[N], T2 (&b)[N] ) noexcept(/* see below */);
// (1)
template< class T >
void swap( T& a, T& b );
// (2)
template< class T2, std::size_t N >
void swap( T2 (&a)[N], T2 (&b)[N] );
Exchanges the given values.
-
(1) Swaps the values
a
andb
.Overload ResolutionThis overload does not participate in overload resolution unlessstd::is_move_constructible_v<T> && std::is_move_assignable_v<T>
istrue
. (since C++17) -
(2) Swaps the arrays
a
andb
. In effect callsstd::swap_ranges(a, a + N, b)
.Overload ResolutionThis overload does not participate in overload resolution unlessstd::is_swappable_v<T2>
istrue
. (since C++17)
Parameters
a b | The values to be swapped. |
Type requirements
T | MoveConstructible, MoveAssignable (since C++11) CopyConstructible, CopyAssignable (until C++11) |
T2 | Swappable |
Return value
(none)
Complexity
- (1) - Constant.
- (1) - Linear in
N
.
Exceptions
Before C++11 no exceptions were thrown.
-
(1)
- since C++11
noexcept specification:
noexcept(
std::is_nothrow_move_constructible<T>::value &&
std::is_nothrow_move_assignable<T>::value
) -
(2)
- since C++17
- until C++17
noexcept specification:
noexcept(std::is_nothrow_swappable_v<T2>)
noexcept specification:
noexcept(
noexcept(swap(*a, *b))
)The lookup for the identifier swap in the exception specification finds this function template in addition to anything found by the usual lookup rules, making the exception specification equivalent to C++17
std::is_nothrow_swappable
.
The overloads with a template parameter named ExecutionPolicy
report errors as follows:
- If execution of a function invoked as part of the algorithm throws an exception and
ExecutionPolicy
is one of the standard policies,std::terminate
is called. For none otherExecutionPolicy
, the behavior is implementation-defined. - If the algorithm fails to allocate memory,
std::bad_alloc
is thrown.
Specializations
- until C++20
The expected way to make a program-defined type swappable is to provide a non-member function swap in the same namespace as the type: see Swappable for details.
The following overloads are already provided by the standard library:
std::swap(std::pair) | Specializes the |
std::swap(std::tuple) (since C++11) | Specializes the |
std::swap(std::shader_ptr) (since C++11) | Specializes the |
std::swap(std::weak_ptr) (since C++11) | Specializes the |
std::swap(std::unique_ptr) (since C++11) | Specializes the |
std::swap(std::function) (since C++11) | Specializes the |
std::swap(std::basic_string) | Specializes the |
std::swap(std::array) (since C++11) | Specializes the |
std::swap(std::deque) (since C++11) | Specializes the |
std::swap(std::forward_list) (since C++11) | Specializes the |
std::swap(std::list) | Specializes the |
std::swap(std::vector) | Specializes the |
std::swap(std::map) | Specializes the |
std::swap(std::multimap) | Specializes the |
std::swap(std::set) | Specializes the |
std::swap(std::multiset) | Specializes the |
std::swap(std::unordered_map) (since C++11) | Specializes the |
std::swap(std::unordered_multimap) (since C++11) | Specializes the |
std::swap(std::unordered_set) (since C++11) | Specializes the |
std::swap(std::unordered_multiset) (since C++11) | Specializes the |
std::swap(std::queue) (since C++11) | Specializes the |
std::swap(std::priority_queue) (since C++11) | Specializes the |
std::swap(std::stack) (since C++11) | Specializes the |
std::swap(std::valarray) (since C++11) | Specializes the |
std::swap(std::basic_stringbuf) (since C++11) | Specializes the |
std::swap(std::basic_istringstream) (since C++11) | Specializes the |
std::swap(std::basic_ostringstream) (since C++11) | Specializes the |
std::swap(std::basic_stringstream) (since C++11) | Specializes the |
std::swap(std::basic_filebuf) (since C++11) | Specializes the |
std::swap(std::basic_ifstream) (since C++11) | Specializes the |
std::swap(std::basic_ofstream) (since C++11) | Specializes the |
std::swap(std::basic_fstream) (since C++11) | Specializes the |
std::swap(std::basic_syncbuf) (since C++20) | Specializes the |
std::swap(std::basic_spanbuf) (since C++23) | Specializes the |
std::swap(std::basic_ispanstream) (since C++23) | Specializes the |
std::swap(std::basic_ospanstream) (since C++23) | Specializes the |
std::swap(std::basic_spanstream) (since C++23) | Specializes the |
std::swap(std::basic_regex) (since C++11) | Specializes the |
std::swap(std::match_results) (since C++11) | Specializes the |
std::swap(std::thread) (since C++11) | Specializes the |
std::swap(std::unique_lock) (since C++11) | Specializes the |
std::swap(std::shared_lock) (since C++14) | Specializes the |
std::swap(std::promise) (since C++11) | Specializes the |
std::swap(std::packaged_task) (since C++11) | Specializes the |
std::swap(std::optional) (since C++17) | Specializes the |
std::swap(std::any) (since C++17) | Specializes the |
std::swap(std::variant) (since C++17) | Specializes the |
std::swap(std::basic_stacktrace) (since C++17) | Specializes the |
swap(std::filesystem::path) (since C++17) | Specializes (hidden friend) the |
swap(std::expected) (since C++23) | Specializes (hidden friend) the |
swap(std::jthread) (since C++20) | Specializes (hidden friend) the |
swap(std::move_only_function) (since C++23) | Specializes (hidden friend) the |
swap(std::stop_source) (since C++20) | Specializes (hidden friend) the |
swap(std::stop_token) (since C++20) | Specializes (hidden friend) the |
Examples
#include <algorithm>
#include <iostream>
namespace Ns
{
class A
{
int id {};
friend void swap(A& lhs, A& rhs)
{
std::cout << "swap(" << lhs << ", " << rhs << ")\n";
std::swap(lhs.id, rhs.id);
}
friend std::ostream& operator<<(std::ostream& os, A const& a)
{
return os << "A::id=" << a.id;
}
public:
A(int i) : id {i} {}
A(A const&) = delete;
A& operator = (A const&) = delete;
};
}
int main()
{
int a = 5, b = 3;
std::cout << a << ' ' << b << '\n';
std::swap(a, b);
std::cout << a << ' ' << b << '\n';
Ns::A p {6}, q {9};
std::cout << p << ' ' << q << '\n';
// std::swap(p, q); // error, type requirements are not satisfied
swap(p, q); // OK, ADL finds the appropriate friend `swap`
std::cout << p << ' ' << q << '\n';
}
5 3
3 5
A::id=6 A::id=9
swap(A::id=6, A::id=9)
A::id=9 A::id=6
Hover to see the original license.