std::swap
来自cppreference.com
<tbody>
</tbody>
| 在标头 <algorithm> 定义
|
(C++11 前) |
|
| 在标头 <utility> 定义
|
(C++11 起) |
|
| 在标头 <string_view> 定义
|
||
template< class T > void swap( T& a, T& b ); |
(1) | (C++11 起为条件 noexcept) (C++20 起为 constexpr) |
template< class T2, std::size_t N > void swap( T2 (&a)[N], T2 (&b)[N] ); |
(2) | (C++11 起为条件 noexcept) (C++20 起为 constexpr) |
交换给定值。
1) 交换
a 与 b。
|
此重载只有在 |
(C++17 起) |
2) 交换数组
a 与 b。等价于调用 std::swap_ranges(a, a + N, b)。
|
此重载只有在 |
(C++17 起) |
参数
| a, b | - | 要交换的值 |
| 类型要求 | ||
-T 必须满足可复制构造 (CopyConstructible) 与可复制赋值 (CopyAssignable) (C++11 前)可移动构造 (MoveConstructible) 与可移动赋值 (MoveAssignable) (C++11 起)。
| ||
-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 成线性。特化
|
|
(C++20 前) |
符合预期的使得由程序定义的类型可交换的方式是,在与该类型相同的命名空间中提供非成员函数 swap:细节见可交换 (Swappable) 。
标准库已提供下列重载:
(C++11) |
特化 std::swap 算法 (函数模板) |
(C++11) |
特化 std::swap 算法 (函数模板) |
(C++11) |
特化 std::swap 算法 (函数模板) |
(C++11) |
特化 std::swap 算法 (函数模板) |
(C++11) |
特化 std::swap 算法 (函数模板) |
(C++11) |
特化 std::swap 算法 (函数模板) |
| 特化 std::swap 算法 (函数模板) | |
(C++11) |
特化 std::swap 算法 (函数模板) |
| 特化 std::swap 算法 (函数模板) | |
(C++11) |
特化 std::swap 算法 (函数模板) |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
(C++11) |
特化 std::swap 算法 (函数模板) |
| 特化 std::swap 算法 (函数模板) | |
(C++11) |
特化 std::swap 算法 (函数模板) |
(C++11) |
特化 std::swap 算法 (函数模板) |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
| 特化 std::swap 算法 (函数模板) | |
(C++11) |
特化 std::swap 算法 (函数模板) |
| 特化 std::swap 算法 (函数模板) | |
(C++11) |
特化 std::swap 算法 (函数) |
(C++11) |
特化 std::swap 算法 (函数模板) |
(C++14) |
特化 std::swap 算法 (函数模板) |
(C++11) |
特化 std::swap 算法 (函数模板) |
| 特化 std::swap 算法 (函数模板) | |
(C++17) |
特化 std::swap 算法 (函数模板) |
(C++17) |
特化 std::swap 算法 (函数) |
(C++17) |
特化 std::swap 算法 (函数模板) |
| 特化 std::swap 算法 (函数模板) | |
(C++17) |
特化 std::swap 算法 (函数) |
(C++23) |
特化 std::swap 算法 (函数) |
(C++20) |
特化 std::swap 算法 (函数) |
| 特化 std::swap 算法 (函数) | |
(C++20) |
特化 std::swap 算法 (函数) |
(C++20) |
特化 std::swap 算法 (函数) |
示例
运行此代码
#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); // 错误,不满足类型要求
swap(p, q); // OK:实参依赖查找找到了合适的友元 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
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| 缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
|---|---|---|---|
| LWG 227 | C++98 | T 不需要满足可复制构造 (CopyConstructible) 或可默认构造 (DefaultConstructible) (因此不保证能构造 T 类型的临时对象)
|
T 也需要满足可复制构造 (CopyConstructible) |
| LWG 809 | C++98 | 数组无法交换 | 添加重载 (2) |
| LWG 2554 | C++11 | 因为名称查找问题,交换多维数组无法是 noexcept 的
|
使之可能 |
参阅
(C++20) |
交换两个对象的值 (定制点对象) |
| 交换两个迭代器所指向的元素 (函数模板) | |
| 交换两个范围的元素 (函数模板) | |
(C++14) |
替换实参为一个新值,并返回它先前的值 (函数模板) |