移动矢量中的一系列元素与复制相比有什么好处?

What is the benefit of moving a range of elements in a vector vs. copying?

考虑以下片段(在大型模拟代码中看到类似的东西)

std::vector<int> v1{1,2,3,4,5,6,7};
std::vector<int> v2;

std::move(v1.begin() + 2, v1.end(), back_inserter(v2));

在这里,我将一系列元素从 v1 移动到 v2,但是这样做与复制相比有什么特别的优势吗?我实际上并没有看到这里的 move 有什么优势,因为它在 int 的范围内运行。事实上,由于我们正在处理 POD 类型,我认为不会发生任何变化。

如果我们想将整个 v1 转移到 v2,那么我们可以这样做:

v2 = std::move(v1);

此处的转换将允许 v2 现在拥有指向以前由 v1 拥有的连续内存范围的指针,从而避免复制。

但是在元素范围前的移动中,我看不出有什么用。

Here, I am moving a range of elements from v1 to v2, but is there any particular advantage to doing this vs. copying?

。这一切都只是一个范围应对,因为您对原始类型使用 std::move 只是应对。因此,如果你有:

std::vector<int> v2{v1.begin() + 2, v1.end()};

因此,您的调查结果是正确的。但是,它被称为fundamental types/ primitive types,而不是PODs。


But in the former move of a range of elements, I don't see the usefulness.

考虑 std::vector</*expensive copy type*/> 的情况,在这种情况下,只要有可能,移动基础范围元素是有意义的。

例如考虑 std::vector<std::string> 案例

std::vector<std::string> v1{ "1","2","3","4","5","6","7" };
std::vector<std::string> v2;
// reserve memory for unwanted reallocations
v2.reserve(std::distance(v1.begin() + 2, v1.end()));

// moves the string element in the range
std::move(v1.begin() + 2, v1.end(), back_inserter(v2));

// v1 now: 1 2
// v2 now: 3 4 5 6 7 

(See a demo here)


作为旁注,对于迭代器,代替 std::move 单独一行中的范围,也可以使用 std::make_move_iterator,在声明时进行范围移动构造(如果有意义) .

#include <iterator> // std::make_move_iterator

std::vector<std::string> v1{ "1","2","3","4","5","6","7" };
std::vector<std::string> v2{ std::make_move_iterator(v1.begin() + 2),
   std::make_move_iterator(v1.end()) };