Reputation: 667
In the code below, which is supposed to be an implementation of ranges::rotate:
auto second(std::vector<int>& v, std::vector<int>::iterator new_first) -> std::vector<int>::const_iterator {
auto copy = std::vector<int>(v.begin(), new_first);
v.erase(v.begin(), new_first);
return v.insert(v.end(), copy.begin(), copy.end());
}
what is actually happening in the first 2 lines of the function where the new_first iterator isn't necessarily at the end? I've only seen examples where the second parameter is specifically at the end.
Upvotes: 0
Views: 245
Reputation: 1529
auto copy = std::vector<int>(v.begin(), new_first);
You are copying first new_first - v.begin()
elements to a new vector named copy
.
v.erase(v.begin(), new_first);
You are erasing the same new_first - v.begin()
elements from the original vector.
v.insert(v.end(), copy.begin(), copy.end());
You are inserting all the elements of copy
into the original vector. So basically you've rotated the vector v
to the right by new_first - v.begin()
elements.
Therefore, if your v was {1,2,3,4,5}
in the beginning and new_first points to say 4
, then the return vector is {4,5,1,2,3}
Upvotes: 1
Reputation: 60208
Let's say the arguments to the function look like this:
v : { 1, 2, 3, 4, 5}
new_first ^
Then this line:
auto copy = std::vector<int>(v.begin(), new_first);
uses the constructor of vector
that takes 2 iterators to construct the copy
variable:
v : { 1, 2, 3, 4, 5}
new_first ^
copy : {1, 2}
Then this line:
v.erase(v.begin(), new_first);
uses the erase method of vector
to remove the initial elements:
v : { 3, 4, 5}
copy : {1, 2}
And finally, this line:
return v.insert(v.end(), copy.begin(), copy.end());
uses the insert method of vector
to copy the initial elements (stored in copy
), to the end of v
, and returns an iterator to the first inserted element:
v : { 3, 4, 5, 1, 2 }
return ^
effectively implementing rotate
.
Upvotes: 2