# std::swap

< cpp‎ | algorithm

定义于头文件 `<algorithm>` |  | (C++11 前)
定义于头文件 `<utility>` |  | (C++11 起)
定义于头文件 `<string_view>` |  | (C++17 起)
| (1) |
template< class T > void swap( T& a, T& b ); |  | (C++11 前)
template< class T > void swap( T& a, T& b ) noexcept(/* see below */); |  | (C++11 起) (C++20 前)
template< class T > constexpr void swap( T& a, T& b ) noexcept(/* see below */); |  | (C++20 起)
| (2) |
template< class T2, std::size_t N > void swap( T2 (&a)[N], T2 (&b)[N]) noexcept(/* see below */); |  | (C++11 起) (C++20 前)
template< class T2, std::size_t N > constexpr void swap( T2 (&a)[N], T2 (&b)[N]) noexcept(/* see below */); |  | (C++20 起)

交换给定值

1) 交换 `a` 与 `b` 。此重载仅若 std::is_move_constructible_v<T> && std::is_move_assignable_v<T> 为 true 才参与重载决议。 (C++17 起)
2) 交换 `a` 与 `b` 数组。等效于调用 std::swap_ranges(a, a+N, b) 。此重载仅若 std::is_swappable_v<T2> 为 true 才参与重载决议。 (C++17 起)

### 参数

a, b | - | 要交换的值
类型要求
- `T` 必须满足可移动赋值 (MoveAssignable) 和 可移动构造 (MoveConstructible) 的要求。
- `T2` 必须满足可交换 (Swappable) 的要求。

### 返回值

（无）

### 异常

1)

（无） | (C++11 前)
`noexcept` 说明： noexcept( std::is_nothrow_move_constructible<T>::value && std::is_nothrow_move_assignable<T>::value ) | (C++11 起)

2)

`noexcept` 说明： noexcept(noexcept(swap(*a, *b))) 异常规定中标识符 `swap` 的查找在通常查找规则的所找到的任何内容外，还会找到此函数模板，这使得异常规定等价于 C++17 std::is_nothrow_swappable 。 | (C++11 起) (C++17 前)
`noexcept` 说明： noexcept(std::is_nothrow_swappable_v<T2>) | (C++17 起)

### 复杂度

1) 常量
2) 与 N 成线性

### 特化

`std::swap` 可以对程序定义类型在命名空间 std 中特化，但 ADL 不会寻找这些特化（命名空间 std 不是与程序定义类型关联的空间）。 | (C++20 前)

令程序定义类型可交换的期待方式是在与该类型相同的命名空间中提供非成员函数 swap ：细节见可交换 (Swappable) 。

标准库已提供下列重载：

std::swap(std::pair) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::tuple) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::shared_ptr) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::weak_ptr) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::unique_ptr) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::function) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::basic_string) | 特化 std::swap 算法 (函数模板)
std::swap(std::array) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::deque) | 特化 std::swap 算法 (函数模板)
std::swap(std::forward_list) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::list) | 特化 std::swap 算法 (函数模板)
std::swap(std::vector) | 特化 std::swap 算法 (函数模板)
std::swap(std::map) | 特化 std::swap 算法 (函数模板)
std::swap(std::multimap) | 特化 std::swap 算法 (函数模板)
std::swap(std::set) | 特化 std::swap 算法 (函数模板)
std::swap(std::multiset) | 特化 std::swap 算法 (函数模板)
std::swap(std::unordered_map) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::unordered_multimap) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::unordered_set) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::unordered_multiset) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::queue) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::priority_queue) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::stack) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::valarray) (C++11) | 特化 std::swap() 算法 (函数模板)
std::swap(std::basic_stringbuf) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::basic_istringstream) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::basic_ostringstream) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::basic_stringstream) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::basic_filebuf) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::basic_ifstream) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::basic_ofstream) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::basic_fstream) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::basic_syncbuf) (C++20) | 特化 std::swap 算法 (函数模板)
std::swap(std::basic_regex) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::match_results) (C++11) | 特化 `std::swap` 算法 (函数模板)
std::swap(std::thread) (C++11) | 特化 std::swap 算法 (函数)
std::swap(std::unique_lock) (C++11) | std::swap 对 `unique_lock` 的特化 (函数模板)
std::swap(std::promise) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::packaged_task) (C++11) | 特化 std::swap 算法 (函数模板)
std::swap(std::optional) (C++17) | 特化 std::swap 算法 (函数模板)
std::swap(std::any) (C++17) | 特化 std::swap 算法 (函数)
std::swap(std::variant) (C++17) | 特化 std::swap 算法 (函数模板)
std::swap(std::filesystem::path) | 交换二个路径 (函数)

### 示例

    #include <algorithm>
    #include <iostream>

    int main()
    {
       int a = 5, b = 3;

       // 前
       std::cout << a << ' ' << b << '\n';

       std::swap(a,b);

       // 后
       std::cout << a << ' ' << b << '\n';
    }

输出：

    5 3
    3 5

### 缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

DR | 应用于 | 出版时的行为 | 正确行为
--- | --- | --- | ---
LWG 2554 | C++11 | 因为名称查找问题，交换多维数组无法为 `noexcept` | 使之可能

### 参阅

iter_swap | 交换两个迭代器所指向的元素 (函数模板)
swap_ranges | 交换两个范围的元素 (函数模板)
exchange (C++14) | 将实参替换为一个新值，并返回其先前值 (函数模板)