将一个向量附加到另一个向量时,为什么移动元素比复制它们更便宜?

Bar*_*raa 2 c++ vector

假设我有两个向量,src并且dst我想附加src到 的末尾dst

我注意到有关此任务的大多数答案都建议这样做:

     dst.insert(dst.end(),
                std::make_move_iterator(src.begin()),
                std::make_move_iterator(src.end()));
Run Code Online (Sandbox Code Playgroud)

对此:

    dst.insert(dst.end(), src.begin(), src.end());
Run Code Online (Sandbox Code Playgroud)

据我所知,将元素推入(插入)向量需要在两种情况下为向量末尾的插入元素分配空间,以确保内存连续性,并且我假设在这种情况下 和 成本copymove相同的。

移动物体将使它们立即被摧毁,这是这样做的唯一好处,还是我还缺少其他东西?

编辑: 您能解释一下在这两种情况下:

  1. 向量包含纯数据,例如:int。
  2. 向量包含类对象。

Wal*_*ter 5

事实上,如果复制和移动元素的成本相同(在您的示例中,元素类型为int),那么就没有区别。

移动仅对本身将数据存储在堆上的元素产生影响,即使用分配的内存(例如,如果元素是std::stringstd::vector<something>)。在这种情况下,移动或复制元素会产生(可能巨大的)差异(提供移动构造函数并operator=(value_type&&)正确实现/启用),因为移动仅将指针复制到已分配的内存,而复制很深:它分配新的内存并复制所有数据,包括递归深复制(如果适用)。

至于与 中存储的数据相关的成本std::vector,如果附加元素超出容量,则会产生一些成本。在这种情况下,整个向量将被调整大小,包括移动其所有元素。其原因是std::vector,根据规范,将其所有元素存储在单个数组中。如果附加容器是代码中的频繁操作,您可能需要考虑其他容器,例如std::liststd::deque