STL list::splice - iterator validity

c++, list, stl

Solution

It's only a guess, but they might have written that to imply that `it` is now "invalid" in the sense that it is no longer a valid iterator of `mylist1`, but instead becomes a valid iterator of `mylist2`.

But still, and I guess you already knew that, it is a valid iterator, so the wording is misleading. You need to be careful, though, as it means that after the second splice-operation, for example, you can no longer do:

std::distance( mylist1.begin(), it );

but need to use

std::distance( mylist2.begin(), it );

as the first would be illegal.

The standard clearly defines it that way in:

23.3.5.5 list operations [list.ops]

`void splice(const_iterator position, list& x, const_iterator i);` `void splice(const_iterator position, list&& x, const_iterator i);`

7 Effects: Inserts an element pointed to by `i` from list `x` before `position` and removes the element from `x`. The result is unchanged if `position == i` or `position == ++i`. Pointers and references to `*i` continue to refer to this same element but as a member of `*this`. Iterators to `*i` (including `i` itself) continue to refer to the same element, but now behave as iterators into `*this`, not into `x`.

So, if your compiler/STL invalidates the iterator, this is clearly a bug.

Problem

I'm reading how "list::splice" works and I don't understand something: ``` mylist1.splice (it, mylist2); // mylist1: 1 10 20 30 2 3 4 // mylist2 (empty) // "it" still points to 2 (the 5th element) mylist2.splice (mylist2.begin(),mylist1, it); // mylist1: 1 10 20 30 3 4 // mylist2: 2 // "it" is now invalid. it = mylist1.begin(); std::advance(it,3); // "it" points now to 30 mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end()); // mylist1: 30 3 4 1 10 20 ``` in the first and third splice the it iterator is still valid, but why isn't it in the second splice? According to the documentation: Iterator validity No changes on the iterators, pointers and references related to the container before the call. The iterators, pointers and references that referred to transferred elements keep referring to those same elements, but iterators now iterate into the container the elements have been transferred to. thus it should still be valid

Original source

Related problems