Consider the following snippet (saw something analogous to this in a large simulation code)
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));
Here, I am moving a range of elements from v1
to v2
, but is there any particular advantage to doing this vs. copying? I do not actually see what the advantage of the move
here would be since it's operating on a range of int
s. In fact, I do not believe any move is occurring since we are dealing with POD types.
If we instead wanted to transfer the entire v1
to v2
, then we could do:
v2 = std::move(v1);
The cast here would allow v2
to now own the pointer to the contiguous range of memory previously owned by v1
, thus avoiding a copy.
But in the former move of a range of elements, I do not see the usefulness.
Here, I am moving a range of elements from
v1
tov2
, but is there any particular advantage to doing this vs. copying?
No. Here is all happened just a range coping, because your usage of std::move
for primitive types just do coping. Therefore it does the same as simple if you would have:
std::vector<int> v2{v1.begin() + 2, v1.end()};
Therefore you are correct about the findings. However, it is called fundamental types/ primitive types, not PODs.
But in the former move of a range of elements, I don't see the usefulness.
Consider the case of std::vector</*expensive copy type*/>
, in which it makes sense to have a move of the underlying range elements, whenever is possible.
For instance consider the std::vector<std::string>
case
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
As a side note, instead of std::move
the range in a separate line, for iterators, one could also use std::make_move_iterator
, to do the range move construction while declaration (if make sence).
#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()) };