C++11 将一个 vector move 到另一个 vector - 将右值引用传递给构造函数

标签 c++ move-semantics

我正在尝试理解 C++ move 语义、std::move() 和右值引用。

我已经实现了这个例子。

#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;
}

我想知道这实际上是将 vector oldData move 到 newData 还是在幕后进行复制。

最佳答案

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

  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 move 到 newData。这是 a quote from cppreference :

6) Move constructor. Constructs the container with the contents of other using move semantics. Allocator is obtained by move-construction from the allocator belonging to other. After the move, other is guaranteed to be empty().

7) Allocator-extended move constructor. Using alloc as the allocator for the new container, moving the contents from other; if alloc != other.get_allocator(), this results in an element-wise move. (in that case, other is not guaranteed to be empty after the move)

在您的特定情况下, vector 有一个默认分配器,这意味着只有第 (6) 项适用。然而,如果有人传递了一个分配器,那么事情就会变得更有趣。

以下是关于复杂性主题的 cppreference 的其余部分:

6) Constant.

7) Linear if alloc != other.get_allocator(), otherwise constant.

同样,在您的情况下,复杂度为 O(1),但使用分配器后事情会变得更有趣。

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

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

关于C++11 将一个 vector move 到另一个 vector - 将右值引用传递给构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55334377/

相关文章:

c++ - 为什么不能 move 这些变量?

c++ - 在 C++ 中使用 linux 系统调用获取我 child 的 pid

c++ - 由于从结构头创建 vector 数组而出现错误 LNK2019?

c++ - c++返回值优化生成的等价代码

c++ - 如何在 Doxygen 中为不同范围的模板值添加行为描述?

c++ - 具有 move 构造函数的 C++ 接口(interface)适配器类

C++ 将 std::strings 从 STL 容器复制到另一个 STL 字符串

c++ - 将局部变量声明为右值引用是否无用,例如T&& r = move (v)?

c++ - 使用隐式可转换对象调用 move 重载函数时出现编译错误

c++ - 为什么复制和 move 构造函数一起调用?