std::swap
| 定义于头文件 <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) |
交换给定的值。
a 和 b。
|
仅当 |
(C++17 起) |
a 和 b。等价于 std::swap_ranges(a, a + N, b)。
|
仅当 |
(C++17 起) |
参数
| a, b | - | 需要交换的值 |
| 类型要求 | ||
-
T
必须满足
CopyConstructible
与
CopyAssignable
(C++11 前)
MoveConstructible
与
MoveAssignable
(C++11 起)
的要求。
|
||
-
T2
必须满足
Swappable
的要求。
|
||
返回值
(无)
异常处理
|
(无) |
(C++11 前) |
|
noexcept
规范:
noexcept
(
std::
is_nothrow_move_constructible
<
T
>
::
value
&&
|
(C++11 起) |
|
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 起) |
复杂度
特化
|
|
(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
算法
(函数模板) |
|
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
特化
std::swap
算法
(函数模板) |
|
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
特化
std::swap
算法
(函数模板) |
|
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
特化
std::swap
算法
(函数模板) |
|
|
特化
std::swap
算法
(函数模板) |
|
|
特化
std::swap
算法
(函数模板) |
|
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
(C++20)
|
特化
std::swap
算法
(函数模板) |
|
(C++23)
|
特化
std::swap
算法
(函数模板) |
|
特化
std::swap
算法
(函数模板) |
|
|
特化
std::swap
算法
(函数模板) |
|
|
特化
std::swap
算法
(函数模板) |
|
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
(C++11)
|
特化
std::swap
算法
(函数) |
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
(C++14)
|
特化
std::swap
算法
(函数模板) |
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
|
(C++11)
|
特化
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
算法
(函数) |
|
(C++23)
|
特化
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); // 正确:ADL找到了合适的友元函数 `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
未被要求为
CopyConstructible
或
DefaultConstructible
(可能无法构造
T
类型的临时对象)
|
T
同时需要
满足 CopyConstructible |
| LWG 809 | C++98 | 无法交换数组 | 添加重载 (2) |
| LWG 2554 | C++11 |
由于名称查找问题,交换多维数组永远
不能声明为 noexcept |
已修复可用 |
另见
(C++20) |
交换两个对象的值 (定制点对象) |
| 交换两个迭代器所指向的元素 (函数模板) | |
| 交换两个范围的元素 (函数模板 & 算法函数对象) | |
(C++20) |
|
(C++14) |
将实参替换为新值并返回其之前的值 (函数模板) |