为什么 std::move 没有移动
Why std::move didn't move
在vs13中编写了以下代码:
std::vector<std::string> myvector(1000);
std::fill(myvector.begin(), myvector.end(), "Hello World");
std::vector<std::string> pushto;
for (auto s: myvector)
pushto.push_back(std::move(*s));
有效但没有移动,而是调用了字符串复制ctor。myvector
在最后仍然有他的"你好世界"。使用像这样的常规c++98迭代:
std::vector<std::string> myvector(1000);
std::fill(myvector.begin(), myvector.end(), "Hello World");
std::vector<std::string> pushto;
for (auto s = myvector.begin(); s != myvector.end();s++)
pushto.push_back(std::move(*s));
事实上起了作用,并呼吁采取行动。myvector
字符串为空。为什么第一个更现代的符号不起作用?
在您使用for (auto s: myvector)
的第一个示例中,s
在本例中是当前迭代中值的副本。要完成您想要的,您应该通过引用for (auto& s: myvector)
来完成。
请注意,不能保证在std::move
之后清空字符串,此调用只是将其参数强制转换为右值引用(&&
)。其他函数(如std::vector::push_back
)的右值引用参数重载可能会释放其argument资源。
正如@Polikdir所说,拷贝来自您在(auto s: myvector)
中制作的拷贝。一种方法是使用循环的范围,使用&&
(转发参考)或&
(正常参考):
for (auto & val : myvector)
pushto.push_back(std::move(val));
虽然不为人所知,但有一种专门的算法可以在容器之间移动对象。它实际上也被称为std::move
。
std::move(s.begin(), s.end(), std::back_inserter(pushto));
编辑:
q: 既然std::move只是强制转换为右值引用,那真的需要吗?在这种情况下,std::move不是多余的吗否,因为变量(如val)不能是r值引用。这就是为什么我们需要在通用引用上调用std::forward<T>
。
另请注意:什么是`auto&;e`do基于范围的循环?
相关文章:
- 当 std::move 与 C 样式数组或不移动对象时会发生什么
- 如何在没有 std::move 的情况下移动临时对象
- 为什么 std::move 不将默认移动构造函数中的源变量更改为默认值?
- 使用 std::move 将参数传递给函数,如果该参数声明为按值传递或使用移动操作数 &&,是否有区别?
- C++:我应该在 return 语句中显式使用 std::move() 来强制移动吗?
- 如何使用 std::move() 将 char[] 移动到向量<char>
- 谁负责释放由 std::move 移动的资源?
- 当使用 std::move 和 lambda 时,何时会发生移动
- 移动变量是否有效,可以在 std::move 之后使用
- C 可以使用MOVE SEMATICS将数据从一个向量移动到另一个向量
- 为什么 std::optional 不允许"move construct and copy assign only"类型的移动分配?
- std::move在将std::string移动到另一个线程时出错
- 为什么 list unique_ptr 的 std::move() 没有<unique_ptr>真正移动它?
- 了解移动构造函数、std::move 和析构函数
- 如果在没有move构造函数的情况下移动对象,会发生什么
- 如果我们只定义复制构造函数/oper=,为什么移动构造函数/move赋值没有隐式声明和定义为删除
- 移动构造函数和 std::move 混淆
- 在移动运算符/赋值运算符中,我应该使用std::move还是std::forward
- 将类(没有默认构造函数)移动到另一个类的move构造函数中
- Do move构造函数需要可移动的属性