std :: move是否可以与左值引用一起使用? std :: move如何在标准容器上工作? [英] Does std::move work with lvalue references? How does std::move work on standard containers?

查看:275
本文介绍了std :: move是否可以与左值引用一起使用? std :: move如何在标准容器上工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#include <vector>

struct A { int a[100]; };

void foo (const A& a) {
  std::vector<A> vA; 
  vA.push_back(std::move(a));  // how does move really happen?
}

int main () {
  A a;
  foo(a);
}

上面的代码编译良好.现在到处都有记载,move避免了复制.
以下是我的查询:

The above code compiles fine. Now everywhere it's written that move avoids copying.
Following are my queries:

  1. move在处理左值时是否真的起作用? [non]-const参考?
  2. 即使使用右值引用",当对象出现时如何避免复制 插入上面的标准容器中?
  1. Does the move really work when one deals with a lvalue [non]-const reference?
  2. Even with "rvalue reference", how is the copy avoided when the object is inserted into a standard container like above?

例如

void foo (A&& a) {  // suppose we invoke this version
  std::vector<A> vA; 
  vA.push_back(std::move(a));  // how copy is avoided?
}

推荐答案

std::move不执行任何操作.它实际上将左值引用转换为右值引用.在这种情况下,移动的结果是const A &&(顺便说一句,这完全没用).

std::move doesn't do a move. It actually casts the lvalue reference to an rvalue reference. In this case, the result of the move is a const A && (which is totally useless by the way).

std::vector对于const A &A &&具有重载,因此将选择const A &的重载,并且const A &&隐式转换为const A &

std::vector has an overload for a const A & and a A &&, so the overload with const A & will get chosen and the const A && is implicitly casted to const A &

可以在const对象上调用std::move的事实对于大多数程序员来说都是奇怪的/意想不到的行为,尽管它在某种程度上是允许的. (很可能他们有一个用例,或者没有一个用例可以阻止它)

The fact that std::move can be called on const objects, is strange/unexpected behavior for most programmers, though it somehow is allowed. (Most likely they had a use case of it, or none to prevent it)

更具体地针对您的示例,将调用类A的move构造函数.由于A是POD,因此很可能只需要进行复制,因为所有位都只需要移动/复制到A的新实例.

More specific for your example, the move constructor of the class A will get called. As A is a POD, this most likely will just do a copy as all bits just have to move/copied to the new instance of A.

由于标准仅指定原始对象必须处于有效(尽管未指定)状态,因此您的编译器可以将位保留在A中,而不必将它们全部重置为0.实际上,大多数编译器将保留这些位就位,因为更改它们需要额外的指令,这对性能不利.

As the standard only specifies that the original object has to be in a valid though unspecified state, your compiler can keep the bits in A in place and doesn't have to reset them all to 0. Actually, most compilers will keep these bits in place, as changing them requires extra instructions, which is bad for performance.

这篇关于std :: move是否可以与左值引用一起使用? std :: move如何在标准容器上工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆