I have a vector that holds items that are either active or inactive. I want the size of this vector to stay small for performance issues, so I want items that have been mark
You might want to consider using a std::list
instead of a std::vector
for your data structure. It is safer (less bug prone) to use when combining erasure with iteration.
Removing items from the middle of a vector will invalidate all iterators to that vector, so you cannot do this (update: without resorting to Wilx's suggestion).
Also, if you're worried about performance, erasing items from the middle of a vector is a bad idea anyway. Perhaps you want to use an std::list
?
As they said, vector's iterators get invalidated on vector::erase()
no matter which form of iterator increment you use. Use an integer index instead.
I agree with wilx's answer. Here is an implementation:
// curFiles is: vector < string > curFiles;
vector< string >::iterator it = curFiles.begin();
while(it != curFiles.end()) {
if(aConditionIsMet) {
it = curFiles.erase(it);
}
else ++it;
}
You can do that but you will have to reshuffle your while()
a bit, I think. The erase()
function returns an iterator to the element next after the erased one: iterator erase(iterator position);
. Quoting from the standard from 23.1.1/7:
The iterator returned from a.erase(q) points to the element immediately following q prior to the element being erased. If no such element exists, a.end() is returned.
Though maybe you should be using the Erase-remove idiom instead.
If someone need working on indexes
vector<int> vector;
for(int i=0;i<10;++i)vector.push_back(i);
int size = vector.size();
for (int i = 0; i < size; ++i)
{
assert(i > -1 && i < (int)vector.size());
if(vector[i] % 3 == 0)
{
printf("Removing %d, %d\n",vector[i],i);
vector.erase(vector.begin() + i);
}
if (size != (int)vector.size())
{
--i;
size = vector.size();
printf("Go back %d\n",size);
}
}