std::swap
来自 cppreference.com
定义在头文件 <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.
只有当 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 必须满足 可复制构造 和 可复制赋值(直到 C++11)可移动构造 和 可移动赋值(自 C++11 起) 的要求。 | ||
-T2 必须满足 可交换 的要求。 |
[编辑] 返回值
(无)
[编辑] 异常
1)
(无) |
(直到 C++11) |
noexcept 规范:
noexcept( std::is_nothrow_move_constructible<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) |
使程序定义的类型 可交换的预期方法是在与类型相同的命名空间中提供一个非成员函数交换:有关详细信息,请参见可交换。
标准库已经提供了以下重载
(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); // 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
[编辑] 缺陷报告
以下更改行为的缺陷报告被追溯应用于先前发布的 C++ 标准。
DR | 应用于 | 已发布的行为 | 正确行为 |
---|---|---|---|
LWG 227 | C++98 | T 不需要可复制构造 或可默认构造(类型 T 的临时对象可能无法构造) |
T 还需要成为可复制构造 |
LWG 809 | C++98 | 无法交换数组 | 添加了重载 (2) |
LWG 2554 | C++11 | 由于名称查找问题,交换多维数组永远 不会是 noexcept |
使其工作 |
[编辑] 另请参阅
(C++20) |
交换两个对象的价值 (自定义点对象) |
交换两个迭代器指向的元素 (函数模板) | |
交换两个元素范围 (函数模板) | |
(C++14) |
用新值替换参数并返回其先前值 (函数模板) |