I'm trying to get information if below code is undefined behavior, I did read here.
In particular I want to be sure that iterator variable iter
will be valid in cases where moved elements overlap destination range.
I think this is not good but can't confirm, and what would be better way to do this?
#include <vector>
#include <iostream>
int main()
{
// move 3, 4 closer to beginning
std::vector<int> vec { 1, 2, 3, 4, 5, 6, 7 };
auto iter = std::move(vec.begin() + 2, vec.end() - 3, vec.begin() + 1);
std::cout << *iter << std::endl;
}
also there is no reference to what this iter
is supposed to point at?
Yes it's well-formed to use std::move
for this case.
(emphasis mine)
When moving overlapping ranges,
std::move
is appropriate when moving to the left (beginning of the destination range is outside the source range) whilestd::move_backward
is appropriate when moving to the right (end of the destination range is outside the source range).
And about the return value,
Output iterator to the element past the last element moved
(d_first + (last - first))
So iter
points to the element following the last element moved, i.e.
// elements of vec (after moved)
// 1, 3, 4, x, 5, 6, 7
// here ^
Note that
After this operation the elements in the moved-from range will still contain valid values of the appropriate type, but not necessarily the same values as before the move.
Here, x
is such an unspecified value. This will probably happen to be another 4
, but this shouldn't be relied upon. Subtle changes, such as a vector of strings instead of numbers, can cause different behavior. For example, the same operation on { "one", "two", "three", "four", "five", "six", "seven" }
would probably result in it being "two"
rather than the "four"
you might expect from seeing the numeric example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With