4

I came across "Add elements to a vector during range-based loop c++11", and wasn't surprised it's not allowed using std::vector because the append can invalidate iterators. However, inserting into std::list doesn't invalidate any of the iterators, so I was wondering if it would be allowed with std::list instead of std::vector.

e.g.

std::list<int> list({1});
for (int &cur : list)
{
    std::cout << cur << " ";
    if (cur < 10)
    {
        list.push_back(cur + 1);
    }
}

It seems to compile fine, but I'm worried it's undefined behaviour.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Daniel McIntosh
  • 522
  • 3
  • 17
  • I believe it's well-defined, for what it's worth. Based on what [range-for loop](https://en.cppreference.com/w/cpp/language/range-for) expands to, and the fact that, indeed, adding to `std::list` doesn't invalidate iterators. – Igor Tandetnik Feb 02 '20 at 01:16

1 Answers1

2

Yes, inserting / removing elements of a std::list does not invalidate pointers, references, or iterators to elements, except for the removed element. Not even the end-iterator is changed or invalidated.

Thus, it is safe.

But as one has to carefully ponder about safety, it is still inadvisable.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • Why the last comment after "_it is safe_"? – Ted Lyngmo Feb 02 '20 at 01:32
  • @TedLyngmo It is still inadvisable, as it depends on the fairly unique peculiarities of that specific container, and is thus susceptible to clumsy future refactoring. – Deduplicator Feb 02 '20 at 01:49
  • Yes, but the question is about that specific container and you concluded that it is safe. I'd just leave it at that. "_Thus, it is safe, for `std::list`_". – Ted Lyngmo Feb 02 '20 at 01:51