6

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?

0

1 Answer 1

5

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) while std::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.

Sign up to request clarification or add additional context in comments.

7 Comments

While the function isn't UB there, it seems fishy to me so I wouldn't call it "fine". The result of the move will be {1, 3, 4, unspecified, 5, 6, 7}, and iter is pointing to the unspecified value.
yes, I took a read and it says "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."
@JosephSible-ReinstateMonica I got what you want to say; I think it's fine for this specified case, i.e. for int.
It might be worth putting a warning about that in your answer. For example, when I did this on strings instead of numbers, { "one", "two", "three", "four", "five", "six", "seven" } turned into { "one", "three", "four", "two", "five", "six", "seven" }.
I'm more interested what will happen if vector is sorted and this element isn't removed manually? I guess you lose control over the vector then.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.