命名空间
变体
操作

C++ 命名要求: 可交换

来自 cppreference.com
 
 
C++ 命名要求
 

此类型的任何左值或右值都可以使用非限定函数调用 swap()std::swap 和用户定义的 swap() 均可见的上下文中与其他类型的任何左值或右值交换。

内容

[编辑] 要求

如果类型 U 与类型 T 可交换,则对于类型 U 的任何对象 u 和类型 T 的任何对象 t,

表达式 要求 语义
#include <algorithm> // C++11 之前

#include <utility> // C++11 之后
using std::swap;
swap(u, t);

调用后,t 的值为调用前 u 所持有的值,而 u 的值为调用前 t 所持有的值。 调用通过重载解析在通过 依赖于参数的查找 找到的所有具有该名称的函数以及在头文件 <algorithm>(C++11 之前)<utility>(C++11 之后) 中定义的两个 std::swap 模板中找到的名为 swap() 的函数。
#include <algorithm> // C++11 之前

#include <utility> // C++11 之后
using std::swap;
swap(t, u);

相同 相同

许多标准库函数(例如,许多算法)期望其参数满足 可交换,这意味着标准库执行交换时,它使用与 using std::swap; swap(t, u); 等效的操作。

典型的实现方法是:

1) 在封闭的命名空间中定义一个非成员交换函数,它可能转发到成员交换函数(如果需要访问非公共数据成员)。
2) 在类中定义一个 友元函数(此方法将特定于类的交换函数隐藏在除了 ADL 之外的名称查找之外)。

[编辑] 备注

未指定标准库函数执行交换时是否实际包含了 <algorithm>(C++11 之前)<utility>(C++11 之后),因此用户提供的 swap() 不应期望它被包含。

[编辑] 示例

#include <iostream>
#include <vector>
 
struct IntVector
{
    std::vector<int> v;
 
    IntVector& operator=(IntVector) = delete; // not assignable
 
    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); // Compiler error! std::swap requires MoveAssignable
    prn();
    std::iter_swap(&v1, &v2); // OK: library calls unqualified swap()
    prn();
    std::ranges::swap(v1, v2); // OK: library calls unqualified 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++ 标准。

DR 应用于 发布的行为 正确的行为
LWG 226 C++98 不清楚标准库如何使用 swap 澄清为同时使用 std:: 和 ADL 找到的 swap

[编辑] 另请参阅

检查类型的对象是否可以与相同或不同类型的对象交换
(类模板) [编辑]
指定类型是否可以交换或两个类型是否可以相互交换
(概念) [编辑]