C ++ 11将一个向量移动到另一个向量 - 将rvalue引用传递给构造函数

问题描述 投票:0回答:1

我试图理解C ++移动语义,std::move()和rvalue引用。

我已经实现了这个例子。

#include <iostream>
#include <vector>

int main()
{
  int totalSize = 6;

  std::vector<double> oldData{ 10, 20, 30 }; 

  oldData.resize(totalSize, 0);

  std::vector<double> newData(std::move(oldData));
  return 0;
}

我想知道这实际上是移动矢量oldDatanewData还是正在复制发生在引擎盖下。

c++ move-semantics
1个回答
1
投票

假设您将无限循环修复为:

  for(unsigned i = 0; i < totalSize - oldData.size(); ++i)
    oldData.push_back(0);

并写下类似的东西:

  for(unsigned i = oldData.size(); i < totalSize; ++i)
    oldData.push_back(0);

或者,甚至更好:

  oldData.resize(totalSize, 0);

然后std::move将所有数据从oldData移动到newData。这是a quote from cppreference

6)移动构造函数。使用move语义构造具有其他内容的容器。分配器是通过属于其他分配器的移动构造获得的。移动后,其他保证为空()。

7)分配器扩展的移动构造函数。使用alloc作为新容器的分配器,从其他容器移动内容;如果alloc!= other.get_allocator(),则会导致元素移动。 (在这种情况下,移动后其他不保证是空的)

在您的特定情况下,向量具有默认分配器,这意味着仅应用第(6)项。但是,如果有人通过分配器,那么事情会变得更有趣。

以下是关于复杂性主题的其余内容:

6)常数。

7)线性如果alloc!= other.get_allocator(),否则为常量。

同样,在您的情况下,复杂性是O(1),但对于分配器,事情变得更有趣。

结论:内部表示必须在O(1)中移动一定数量的指针,而不是逐个移动元素。可以使用一个具有容量和大小整数的指针或三个指针(开始,结束和容量结束)来实现向量。对于所有这些实现,移动是一个简单的玩指针。

但是,如果提供了非默认分配器并且两个向量使用不同的分配器对象,则必须逐个移动或复制这些值。

© www.soinside.com 2019 - 2024. All rights reserved.