std::swap是最安全直接的交换方式,需包含头文件,支持内置类型、stl容器及满足移动语义的自定义类型;禁用异或交换等未定义行为写法。

用 std::swap 是最安全直接的方式
绝大多数情况下,直接调用 std::swap 就够了,它针对内置类型、STL 容器、自定义类型(满足移动语义)都有优化,且不会引发未定义行为。
常见错误是手写临时变量交换却漏掉引用或类型不一致,比如:int a = 1, b = 2; swap(a, b); 如果没 #include <utility></utility> 或没 using,编译会报 ‘swap’ was not declared in this scope。
- 必须包含头文件:
#include <utility></utility>(C++11 起) - 对基本类型、数组、
std::vector等都适用,例如:std::swap(v[0], v[1]); - 若交换自定义类对象,确保该类支持拷贝或移动(否则可能退化为深拷贝,影响性能)
手写交换时为什么不能用异或(a ^= b ^= a ^= b)
这种写法在 C++ 中属于未定义行为(UB),因为同一表达式中多次修改 a 和 b 且无序列点,不同编译器结果可能不同,甚至崩溃。
即使看起来“能跑”,也绝对不要用。典型错误现象:交换后值变 0、程序行为随机、开启优化(-O2)后逻辑失效。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 错误示例:
a ^= b ^= a ^= b;→ 编译通过但行为不可靠 - 正确替代(如真不用
std::swap):int t = a; a = b; b = t; - 注意:如果变量是带副作用的表达式(如
*p++),手写临时变量也要小心求值顺序
模板函数封装交换逻辑要注意引用类型
自己写通用交换函数时,参数必须用右值引用或转发引用,否则无法处理临时对象或 const 对象。
错误写法:template<typename t> void my_swap(T a, T b)</typename> —— 传值导致交换的是副本,原变量不变。
- 正确签名应为:
template<typename t> void my_swap(T& a, T& b)</typename> - 若要支持移动语义,可进一步用完美转发:
template<typename t> void my_swap(T&& a, T&& b)</typename>,但需配合std::forward和重载,复杂度陡增 - 实际项目中,99% 场景下直接用
std::swap更稳妥,它内部已处理好所有边界
指针和引用交换的本质区别
交换两个指针变量(int* p1, *p2)和交换它们指向的值(*p1 和 *p2)是两回事,容易混淆。
- 交换指针本身:
std::swap(p1, p2);→p1指向原来p2的地址 - 交换指针所指内容:
std::swap(*p1, *p2);→ 内存中两个整数值互换 - 若
p1或p2为空,后者会触发段错误;前者完全安全
交换看似简单,但涉及求值顺序、引用语义、模板实例化和底层内存模型——最容易被忽略的是:以为写对了,其实触发了未定义行为,而问题只在特定编译器或优化级别下暴露。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










