命名空间
变体
操作

std::swap

来自 cppreference.com
< cpp‎ | algorithm
 
 
算法库
受约束的算法和范围上的算法 (C++20)
受约束的算法,例如 ranges::copy, ranges::sort, ...
执行策略 (C++17)
排序和相关操作
分区操作
排序操作
二分搜索操作
(在已分区范围上)
集合操作(在排序范围上)
合并操作(在排序范围上)
堆操作
最小/最大操作
(C++11)
(C++17)
字典序比较操作
排列操作
C 库
数值操作
未初始化内存操作
 
定义在头文件 <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) 交换值 ab.

只有当 std::is_move_constructible_v<T> && std::is_move_assignable_v<T>true 时,此重载才参与重载解析。

(自 C++17 起)
2) 交换数组 ab。等效于 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 &&
    std::is_nothrow_move_assignable<T>::value

)
(自 C++11 起)
2)
noexcept 规范:  
noexcept(noexcept(swap(*a, *b)))
在异常规范中查找标识符 swap 时,除了通过通常查找规则找到的任何内容外,还会找到此函数模板,使异常规范等效于 C++17 std::is_nothrow_swappable
(自 C++11 起)
(直到 C++17)
noexcept 规范:  
(自 C++17 起)

[编辑] 复杂度

1) 常数。
2) 线性于 N

[编辑] 特化

std::swap 可以在命名空间 std 中特化 用于程序定义的类型,但这种特化不会被ADL(命名空间 std 不是程序定义类型的关联命名空间)发现。

(直到 C++20)

使程序定义的类型 可交换的预期方法是在与类型相同的命名空间中提供一个非成员函数交换:有关详细信息,请参见可交换

标准库已经提供了以下重载

特化了 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 算法
(函数模板) [编辑]
特化了 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 算法
(函数模板) [编辑]
特化了 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 算法
(函数模板) [编辑]
特化了 std::swap 算法
(函数模板) [编辑]
特化了 std::swap 算法
(函数模板) [编辑]
特化了 std::swap 算法
(函数模板) [编辑]
特化了 std::swap 算法
(函数) [编辑]
特化了 std::swap 算法
(函数模板) [编辑]
特化了 std::swap 算法
(函数模板) [编辑]
特化了 std::swap 算法
(函数) [编辑]
特化了 std::swap 算法
(函数) [编辑]
特化了 std::swap 算法
(函数) [编辑]
特化了 std::swap 算法
(函数) [编辑]
特化了 std::swap 算法
(函数) [编辑]
特化了 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++14)
用新值替换参数并返回其先前值
(函数模板) [编辑]