c++ - std::move 是否与左值引用一起使用? std::move 如何在标准容器上工作?

标签 c++ c++11 reference language-lawyer 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 避免复制。
以下是我的查询:

  1. move 在处理左值时真的有效吗 [非]-const 引用?
  2. 即使有“右值引用”,对象复制时如何避免复制 像上面一样插入标准容器中?

例如

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 不 move 。它实际上将左值引用转换为右值引用。在这种情况下, move 的结果是 const A &&(顺便说一句,这完全没用)。

std::vector 有一个 const A & 和一个 A && 的重载,所以 const A 的重载& 将被选中并且 const A && 被隐式转换为 const A &

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

对于您的示例更具体,将调用类 A 的 move 构造函数。由于 A 是一个 POD,这很可能只会进行复制,因为所有位都必须 move/复制到 A 的新实例。

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

关于c++ - std::move 是否与左值引用一起使用? std::move 如何在标准容器上工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38917130/

相关文章:

c++ - std::string::replace 标准实现?

c++ - 如何获取通用lambda的返回类型和参数类型?

c++ - 我可以在 lambda 捕获子句中声明一个变量吗?

c++ - 具有默认移动构造函数的复合类的移动后使用 POD 部分

java - 在两种不同情况下与对象引用混淆

java - 是否有具有通用引用接口(interface)的标准库?

C++ Opencl 包装器引用计数?

c++ - QuickSort 不排序数组

java - 通过套接字传递对(大)数据区域的引用

c++ - Qt线程不工作