C++ named requirements: Swappable
该类型的任何左值或右值都可以与其他类型的任何左值或右值进行交换,通过在同时可见 std::swap 和用户自定义 swap ( ) 的上下文中使用非限定函数调用 swap ( ) 实现。
目录 |
要求
当类型 U 与类型 T 可交换时,对于任何类型 U 的对象 u 和任何类型 T 的对象 t,
| 表达式 | 要求 | 语义 |
|---|---|---|
|
#include <algorithm> // until C++11
#include <utility> // since C++11
|
调用后,
t
的值为调用前
u
持有的值,
u
的值为调用前
t
持有的值。
|
通过 实参依赖查找 找到的所有同名函数以及头文件 <algorithm> (C++11 前) <utility> (C++11 起) 中定义的两个 std::swap 模板,通过重载决议调用名为 swap ( ) 的函数。 |
|
#include <algorithm> // until C++11
#include <utility> // since C++11
|
同上 | 同上 |
许多标准库函数(例如众多算法)要求其参数满足 可交换 条件,这意味着当标准库执行交换操作时,会采用等效于 using std:: swap ; swap ( t, u ) ; 的方式。
典型实现要么
注释
未指定标准库函数执行交换时是否实际包含 <algorithm> (C++11 前) <utility> (C++11 起) ,因此用户提供的 swap ( ) 不应预期其已被包含。
示例
#include <iostream> #include <vector> struct IntVector { std::vector<int> v; IntVector& operator=(IntVector) = delete; // 不可赋值 void swap(IntVector& other) { v.swap(other.v); } void operator()(auto rem, auto term = " ") { std::cout << rem << "{{"; for (int n{}; int e : v) std::cout << (n++ ? ", " : "") << e; std::cout << "}}" << term; } }; void swap(IntVector& v1, IntVector& v2) { v1.swap(v2); } int main() { IntVector v1{{1, 1, 1, 1}}, v2{{2222, 2222}}; auto prn = [&]{ v1("v1", ", "), v2("v2", ";\n"); }; // std::swap(v1, v2); // 编译错误!std::swap 要求 MoveAssignable prn(); std::iter_swap(&v1, &v2); // 正常:库调用非限定 swap() prn(); std::ranges::swap(v1, v2); // 正常:库调用非限定 swap() prn(); }
输出:
v1{{1, 1, 1, 1}}, v2{{2222, 2222}};
v1{{2222, 2222}}, v2{{1, 1, 1, 1}};
v1{{1, 1, 1, 1}}, v2{{2222, 2222}};
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的C++标准。
| 缺陷报告 | 应用于 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| LWG 226 | C++98 |
标准库如何使用
swap
不够明确
|
明确说明同时使用
std::
和 ADL 查找到的
swap
|
另请参阅
|
(C++17)
(C++17)
(C++17)
(C++17)
|
检查某类型的对象能否与相同或不同类型的对象进行交换
(类模板) |
|
(C++20)
|
规定类型可交换或两个类型可相互交换
(概念) |