Let's say I have this code:
std::vector<Object*> objects;
std::vector<Object*>::iterator iter;
for (iter = objects.begin(); iter != objects.end(); iter++) {
if (condition)
objects.push_back(new Object());
}
However, when push_back occurs, iter
becomes undereferenceable. Without resetting iter
, how do I keep it dereferenceable? If I have to reset it, is there 开发者_运维百科an easy way to do it so iter goes back to where it was before?
I would recommend that you simply access it by index. This completely eliminates the issue.
If you absolutely must use iterators for this:
std::vector<Object*> objects;
std::vector<Object*> newObjects;
std::vector<Object*>::iterator iter;
for (iter = objects.begin(); iter != objects.end(); ++iter)
{
if (condition)
{
newObjects.push_back(new Object());
}
}
std::copy(newObjects.begin(), newObjects.end(), back_inserter<vector<Object*> >(objects));
You will have to result to an old fashioned for loop with numerical indices. Either that, or reserve() the vector before the loop runs to guarantee it won't resize.
Also, raw pointers? Srsly.
The iterator only becomes invalidated if the vector has to reallocate more memory.
To prevent the reallocation of memory pre-allocate all the memory you need with reserve() (assuming you know this size when you allocate the vector).
The easier solution keep an indirect reference to the member (an index in the array).
§23.1/11:
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.
However, it is not explicitly specified, that std::vector::push_back invalidates any iterators.
As most of the other answers already say, you're probably better accessing the vector by index in this case.
However, for completeness: std::list
iterators don't have this "problem". So using list
instead of vector
is a possible solution.
精彩评论