1

Let's say that in the main thread of a C++11 program I build an std::set, fill it with items and extract an iterator it from it. After that, from another thread, I start modifying the set in such a way that elements can only be added to it but not erased.

Is the validity of it assured also while the set is being modified, or should I consider it invalid while the set is being modified by insertion operations from the other thread?

bluescarni
  • 3,937
  • 1
  • 22
  • 33

1 Answers1

4

From section 23.2.1 [container.requirements.general]:

Unless otherwise specified (either explicitly or by defining a function in terms of other functions), invoking a container member function or passing a container as an argument to a library function shall not invalidate iterators to, or change the values of, objects within that container.

For associative containers such as std::set, section 23.2.4 ([associative.reqmts]) says:

The insert and emplace members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.

So your iterators will remain valid after inserting additional items.

However, thread safety is a different topic completely.

Section 17.6.5.9 ([res.on.data.races]) provides that

Operations on iterators obtained by calling a standard library container or string member function may access the underlying container, but shall not modify it.

Since that results in reading the container while it's being updated, it is not necessarily safe to use a std::set iterator while inserting into the collection from another thread. Your implementation may provide a stronger guarantee.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • This is under a single-threaded model. It is still possible that an intermediate state leads invalid iterators, if you perform concurrent operations such as `i++`. – spraff Jan 25 '12 at 17:03
  • Maybe I'm splitting hairs here, but do these guarantees include that the iterator is not invalidated at _any_ point of the invocation of the container member function? I.e., what's preventing an implementation from invalidating an iterator during a call to insert() and the re-validating it before exiting the method? – bluescarni Jan 25 '12 at 17:06
  • @bluescarni: As mentioned, thread safety is a separate topic. I've since added what I believe to be the controlling requirement. – Ben Voigt Jan 25 '12 at 17:09
  • @BenVoigt: thank you very much, still cannot find my way around too quickly in the standard :) Am I correct in understanding that storing the reference instead of the iterator th problem would be avoided? – bluescarni Jan 25 '12 at 17:11
  • @bluescarni: Yes. Different threads accessing different objects is safe. – Ben Voigt Jan 25 '12 at 18:12