使用std::move传递右值引用参数函数的移动语义困惑
为什么std::move后原vector的size没变化?
核心问题是你混淆了右值引用的绑定和实际的移动操作这两个完全不同的概念:
当你用
std::move(v)作为参数传给func(std::vector<std::string>&& vec)时,只是让右值引用vec绑定到了被转换为右值的v上。这个过程没有触发任何vector的资源转移——你只是在函数里读取了vec的size,根本没碰它的内部资源,原v的元素自然不会消失。就像你把快递递到别人手里,对方只是扫了一眼单号没拿走,快递当然还在你这儿。而当你改成值传递参数
std::vector<std::string> vec时,情况就不一样了:这时候会调用vector的移动构造函数(因为你传的是std::move(v)这个右值)。移动构造函数会把v的内部资源(比如存储元素的内存指针)直接转移给新的vec对象,同时把原v置为空状态(size变为0)——这才是你预期的移动语义效果。
如果要让第一个func触发移动操作,你需要在函数内部显式调用移动构造或移动赋值,比如:
void func(std::vector<std::string>&& vec) { std::vector<std::string> moved_vec(std::move(vec)); // 这里才真正触发资源转移 std::cout << "After move, vec has " << vec.size() << " elements" << std::endl; // 此时vec的size会是0 }
这时候再调用func(std::move(v)),原v的size也会变成0,因为vec是v的右值引用,移动操作直接转移了v的资源。
另外要记住:std::move本身只是一个类型转换工具,它不会主动做任何资源转移,只是把左值转换成右值引用,让后续代码有机会调用移动语义相关的函数。
内容的提问来源于stack exchange,提问作者user20082296
相关产品推荐
相关产品推荐

