应使用std::swap而非异或交换:异或仅适用于同类型整型且存在自引用清零、可读性差等问题;std::swap泛型安全、支持移动语义、编译器优化好,C++20还支持constexpr。

用异或运算交换两个整型变量
异或(^)是唯一能安全实现“无临时变量交换”的算术操作,但仅限于相同类型的整型变量,且不能用于浮点数、指针或自定义类型。原理是利用 a ^ a == 0 和 a ^ 0 == a 的性质:a ^= b; b ^= a; a ^= b; 三步后完成交换。
常见错误是写成 a ^= b ^= a ^= b; —— 这属于未定义行为(C++标准不保证赋值顺序),不同编译器结果可能不同,必须拆成三行独立语句。
- 只适用于整型(
int、short、long long等),char也可,但要注意符号扩展 - 若两变量地址相同(比如
swap(&x, &x)),异或会把值清零,需额外判等 - 现代编译器对
std::swap优化极好,手写异或几乎不带来性能提升,反而降低可读性
用 std::swap 是更合理的选择
标准库的 std::swap 在 C++11 后默认使用移动语义,对内置类型直接按位拷贝,对类类型自动调用移动构造/赋值(如果可用),效率不输手写,且语义清晰、泛型安全。
例如:std::swap(a, b); 可用于 int、std::string、std::vector 甚至自定义类(只要满足可移动或可拷贝)。
- 不需要手动处理类型限制,也不怕自引用(
swap(x, x)是明确定义的) - 模板特化支持(如
std::swap对std::array有高效特化版本) - 在
或中声明,C++11 起无需额外头文件(是规范位置)
用加减法交换整型变量?危险!
有人用 a = a + b; b = a - b; a = a - b;,看似可行,但极易溢出。例如 int a = INT_MAX, b = 1;,第一步就触发有符号整数溢出,属于未定义行为。
- 无符号整型虽不溢出,但会回绕(wraparound),逻辑上仍是错误交换(比如
uint8_t a=255, b=1→a先变 0,再变 254,最终结果错乱) - 完全无法推广到浮点数(精度丢失 + NaN/Inf 边界问题)
- 编译器无法对此做有效优化,还可能因中间值依赖阻碍指令重排
为什么不要为“炫技”放弃 std::swap
真正需要无临时变量的场景极少——比如嵌入式系统中寄存器映射的内存地址,或汇编内联约束严格时。日常开发中,追求“不用中间变量”反而暴露对编译器优化和标准库设计的误解。
一个容易被忽略的点:std::swap 在 C++20 引入了 constexpr 支持,意味着它甚至能在编译期交换字面量类型(如 constexpr std::array)。而所有手写技巧都做不到这点。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











