An iterator into a std::set
becomes invalidated if the item it's pointing to is erased. (It does not get invalidated if the set is modified in any other way, which is nice.) However, there is no way to detect whether an iterator has been invalidated or not.
I'm implementing an algorithm that requires me to be able to keep track of members of a std::set
in such a way that I can erase them in constant time, but without risking undefined behaviour if I try to delete the same one twice. If I have two iterators pointing to the same member of a set
, Bad Things will happen if I try to erase both of them.
My question is, how can I avoid this? Is there some way to implement something that behaves like an iterator into a set
, but which knows when it has been invalidated?
Incidentally, I'm using std::set
because this is a performance critical situation and I need the complexity guarantees that set
provides. I'm happy to accept answers that suggest a different data structure, but only if it allows me to (a) access and remove the smallest element in constant time, (b) remove the pointed-to elements in constant time, and (c) insert elements in O(log(N)) time or better. C++11 is OK.
The standard solution to check for existence of an element in the set container ( std::set or std::unordered_set ) is to use its member function find() . If the specified element is found, an iterator to the element is returned; otherwise, an iterator to the end of the container is returned.
Deleting a single element from the set container is very simple in C++. The idea is to pass the given element to the set::erase function, which erases it from the set.
You could keep a set of shared pointers. And every time you store an iterator, pair it with a weak pointer to the element. When you want to erase the element, first check the weak pointer to see if the object still exists.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With