贝利信息

c++ swap函数用法_c++交换两个变量的值

日期:2026-01-23 00:00 / 作者:穿越時空
std::swap是C++标准库中高效交换对象值的函数,定义在中,优先使用移动语义或位交换,避免深拷贝;直接赋值会导致数据丢失,手写临时变量冗余且不通用。

std::swap 是什么,为什么不能直接用赋值

std::swap 是 C++ 标准库中用于交换两个对象值的函数,定义在 头文件里。它不是简单的三行赋值(临时变量 + a=b + b=临时),而是针对不同类型做了优化:对基础类型是位交换,对类类型会优先调用移动语义(如果可用),避免深拷贝开销。

直接写 a = b; b = a; 会导致 b 值丢失,这是初学者常见错误;而手写临时变量虽然可行,但冗余、易错,且无法自动适配自定义类型或容器。

基本用法:交换 int、double、string 等内置/标准类型

只要类型支持移动构造/赋值或拷贝构造/赋值,std::swap 就能用。注意必须显式包含头文件,否则编译报错 ‘swap’ was not declared in this scope

#include 
#include 

int main() { int a = 10, b = 20; std::swap(a, b); // ✅ 安全、高效 std::cout << a << " " << b << "\n"; // 输出: 20 10 }

自定义类怎么让 swap 更快:提供非成员 swap 重载

如果你的类管理动态资源(比如自己 new 的数组),默认的 std::swap 会触发拷贝构造 + 拷贝赋值,性能差还可能抛异常。正确做法是在类所在命名空间中定义非成员 swap 函数,并声明为 friend 或公有接口。

struct Widget {
    int* data;
    Widget(int x) : data(new int(x)) {}
    ~Widget() { delete data; }
    // ... 拷贝/移动操作略
};

// 在 Widget 同一命名空间(全局)中定义 void swap(Widget& a, Widget& b) noexcept { std::swap(a.data, b.data); // 仅交换指针 }

常见陷阱:std::swap 与 ADL 冲突、右值引用误用

最隐蔽的问题是:你写了自定义 swap,但调用时没触发,还是走默认拷贝版。原因常是忘记 ADL 触发条件 —— 比如用了 using std::swap; 后又写 swap(a, b),编译器可能只找 std::swap 而忽略你的版本。

真正复杂的地方在于:当类模板嵌套、继承关系存在时,swap 重载要覆盖所有可能组合,稍有遗漏就退化成低效拷贝 —— 这点很容易被忽略,直到压测时发现内存暴涨或卡顿。