




右值引用是为移动语义和完美转发设计的类型修饰符,不改变对象生命周期;std::move仅强制转为T&&类型,不执行移动;完美转发需std::forward配合万能引用;移动语义需类显式定义且满足条件。
右值引用不是“给右值加引用”,而是为支持移动语义和完美转发而设计的类型系统机制;它本身不改变对象生命周期,但为编译器提供了明确的“可窃取资源”信号。
&& 的本质是类型修饰符,不是绑定规则很多人误以为 && 只能绑定临时对象(如 std::string("hello")),其实只要表达式类型匹配、且满足引用折叠规则,就能绑定。关键在类型推导结果,不在“是不是临时”。
T&& 在模板中可能退化为左值引用(当 T 是左值引用类型时,经引用折叠变成 T&)auto&& x = std::move(y);)是左值——因为它有名字、可取地址,但其类型仍是 T&&
&&
std::move 不移动,只做类型转换std::move 是一个强制转型工具,把任意表达式转成 T&& 类型,从而参与重载选择。它不触发任何内存操作,也不保证后续发生移动——如果目标类型没定义移动构造函数,仍会回退到拷贝。
std::move 后继续使用原对象——未定义行为(除非该类型明确保证移动后状态可读,如 std::unique_ptr 移动后为 nullptr)int、double)调用 std::move 完全无意义,编译器会忽略std::move 反而阻止优化std::forward 和引用折叠std::forward 的作用是:当 T 是左值引用类型时,保持 t 作为左值传递;否则按右值转发。这依赖模板参数 T 是否被推导为引用类型。
T&& 形参)使用,单独写 std::forward(x) 没有意义template void f(T&& t) { g(std::forward(t)); } —— 正确;但若写成 g(std::move(t)),则无论传入左值还是右值,都会强制转右值,破坏转发语义编译器不会为所有类自动生成移动构造函数。只有当类没有用户声明的析构函数、拷贝构造/赋值,且所有成员都可移动时,才隐式生成移动操作。否则必须手动实现。
std::vector 移动后大小为 0,但可安全析构或赋值no
except),否则 std::vector 等容器在扩容时可能放弃移动而改用拷贝最难把握的其实是移动与拷贝边界的语义一致性:什么时候该移动、什么时候该拷贝,取决于资源所有权是否真正转移,而不是类型语法上看起来像不像“临时对象”。很多 bug 出现在误移了本该共享的数据,或在不该移动的地方强行移动导致悬空。