问题描述
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
先前拥有的连续内存范围的指针,从而避免了复制。
但是在一系列要素的前一步中,我看不到有用性。
解决方法
在这里,我正在将一系列元素从
v1
移到v2
,但是有没有 与复制相比有什么特别的优势?
否。这只是发生范围应付,因为您对原始类型使用std::move
确实可以应付。因此,如果您要进行以下操作,它与简单操作一样:
std::vector<int> v2{v1.begin() + 2,v1.end()};
因此,您对发现是正确的。但是,它称为fundamental types/ primitive types,而不是POD。
但是在先前一系列元素的移动中,我看不到有用性。
考虑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
请注意,对于迭代器,也可以使用std::make_move_iterator
来在声明时(如果有意思的话)进行范围移动构造,而不是在单独的行中使用std::move
来代替范围。 / p>
#include <iterator> // std::make_move_iterator
std::vector<std::string> v1{ "1","7" };
std::vector<std::string> v2{ std::make_move_iterator(v1.begin() + 2),std::make_move_iterator(v1.end()) };