C++ 具名要求:可交换 (Swappable)
在 std::swap 与用户定义 swap() 均可见的语境中,此类型的任何左值或右值能与某个其他类型的任何左值或右值,可以用非限定函数调用 swap() 来进行交换。
要求
若对于任意 U 类型的对象 u 和任意 T 类型的对象 t,满足以下情况,则类型 U 与类型 T 可交换:
表达式 | 要求 | 语义 |
---|---|---|
#include <utility> using std::swap; |
调用后,t 的值是 u 在调用前保有的值,而 u 的值是 t 在调用前保有的值。
|
调用名为 swap() 的函数,它是在由实参依赖查找所找到的所有具有这个名字的函数,和定义于头文件 <utility> 中的两个 std::swap 模板中,由重载决议所找到的函数。 |
#include <utility> using std::swap; |
同上 | 同上 |
许多标准库函数(例如许多算法)期待其实参满足可交换 (Swappable) ,这意味着每当标准库进行交换时,都使用等价于 using std::swap; swap(t, u); 的写法。
典型的实现进行二者之一
1) 在外围命名空间中定义非成员 swap,若要求访问非公开数据成员,则它可转发到成员 swap
2) 于类中定义友元函数(此方法对于除 ADL 之外的名字查找隐藏了类特有的 swap)
注解
标准库进行交换时是否实际包含 <utility> 是未指明的,因此用户提供的 swap() 不应当期待它已被包含。
示例
运行此代码
#include <iostream> #include <vector> class IntVector { std::vector<int> v; IntVector& operator=(IntVector) = delete; // 不可赋值 public: void swap(IntVector& other) { v.swap(other.v); } }; void swap(IntVector& v1, IntVector& v2) { v1.swap(v2); } int main() { IntVector v1, v2; // std::swap(v1, v2); // 编译器错误!std::swap 要求可移动赋值 (MoveAssignable) std::iter_swap(&v1, &v2); // OK:标准库调用无限定的 swap() }
参阅
(C++17)(C++17)(C++17)(C++17) |
检查一个类型的对象是否能与同类型或不同类型的对象交换 (类模板) |