Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::list - are the iterators invalidated on move?

Tags:

c++

c++11

c++14

std::list iterators have some very nice properties - they remain valid when any other element is removed, when a new element is added and even when 2 lists are swapped (Iterator invalidation rules)!

Considering following code behaviour and that the iterators are implement by a form of pointer to the actual node which doesn't change when the list is moved, my guess is that the iterators are still valid in the new container when a std::list is moved, but also I can be in the UB area here by accessing invalid memory which actually has the "expected" value.

std::list<int> l1{3, 2, 1};
std::list<int> l2;

auto it = std::prev(l1.end());
std::cout<<l1.size()<<" "<<l2.size()<<" "<<*it<<std::endl;

l2 = std::move(l1);
std::cout<<l2.size()<<" "<<*it<<std::endl;

3 0 1
3 1

Is it guaranteed by the standard if the iterators remain valid when std::list is moved? What about other containers?

like image 434
Mircea Ispas Avatar asked Oct 15 '14 09:10

Mircea Ispas


1 Answers

For containers in general, only swap guarantees that iterators remain valid (and point into the swapped containers).

For std::list, the special member function splice() guarantees that iterators retain their expected meaning.

In general, constructing a container from an rvalue doesn't make guarantees about iterators; the only general requirement is that the new container has the "same value" as the container it was constructed from had originally.

(You can imagine debug iterator implementations that store a reference to the container, and that reference would become dangling after a move.)

like image 81
Kerrek SB Avatar answered Sep 28 '22 01:09

Kerrek SB