std::move本质是将左值强制转换为右值引用的类型转换函数,不真正移动数据;真正“掏空”资源的是用户定义的移动构造函数或移动赋值运算符。
move 不是“把对象搬走”,而是告诉编译器:这个对象可以被“掏空”,后续不再安全使用——它本质是类型转换,不是搬运动作。
为什么 std::move 不真正移动数据?
std::move 只是一个强制类型转换函数,它把左值转成右值引用(T&&),从而允许调用移动构造函数或移动赋值运算符。真正“掏空”资源的是你写的移动构造函数,不是 std::move 本身。
- 没定义移动构造函数?
std::move(x)后仍会调用拷贝构造——编译器不会自动帮你生成移动操作 -
std::move后原对象进入“有效但未指定状态”,比如std::vector移动后size()可能为 0,也可能不为 0,但data()通常为nullptr - 对内置类型(
int、double)或 trivial 类型调用std::move没有意义,编译器本就会按值传递,无额外开销
哪些场景必须显式写 std::move?
只有当你手头是个左值(命名变量),又想让它参与移动语义时,才需要 std::move。常见于:
- 在移动构造函数/赋值函数内部,将成员变量“移交”给新对象:
other.data_(std::move(other.data_)) - 从函数返回局部对象时,现代编译器通常会自动应用 RVO 或移动,但若返回的是参数(如包装函数),需手动
std::move:return std::move(x); - 向容器插入临时对象时,避免意外拷贝:
v.push_back(std::move(temp_obj));
注意:std::vector::push_back(T&&) 重载只接受右值引用;传入左值不加 std::move 就会退化到拷贝版本。
立即学习“C++免费学习笔记(深入)”;