Reputation: 932
Let say we have:
std::vector<Segment*> segments;
...
Segment* dd = new Segment;
segments.emplace_back(dd);
Owner* owner = getOwner();
owner->setSegmentPointer(&(segments.back());
This will not work because of Iterator invalidation rules.
Any subsequent element addition to the vector segments
will render invalid the pointers stored in owner
. How to circumvent this problem keeping the access time of std::vector<>
? (Assuming that we can't use vector.resize
in advance). Is to use std::map<>
the only solution?
Thanks in advance
Upvotes: 0
Views: 285
Reputation: 25536
Each owner can use that pointer to access other elements in the vector.
Apart from being a horrible idea, you could realise it with a std::list
, though:
First, every owner instance gets an iterator to the list, not a pointer to a segment. std::list
has the advantage of not invalidating iterators on insertion/deletion, unless you delete the element an iterator points to.
Via this iterator, you can find the other elements in the list. One problem remains, though: you need to detect safely the begin and end of the list. So you need sentinel values at begin and end, which could be e. g. null pointers, if these do not occur in the list.
One important note: If you need to remove a segment from the list, although an owner still has an iterator to it, you need to find a way to inform the owner about iterator invalidation. There are no means available to get this done automatically!
Upvotes: 2
Reputation: 180935
If you need random access but you need the container to grow without invalidating pointers/references/iterators to the elements then you can use a std::deque
. This will let you grow/shrink from the front or back. If you insert/erase from the middle though that can still invalidate iterators.
Upvotes: 1