I have a std::vector<Shape*>
called scene which stores pointers to Shapes. I need to be able to iterate through the vector, comparing the shape pointed to by the iterator with the next shape in the iterator. If the return of s1->intersects(*s2)
is true, I need to remove both s1 and s2 from the vector. The following code isn't correct, I get an exception vector interator is not incrementable
.
How can I solve this problem?
while (scene.size() > 1)
{
for (std::vector<Shape*>::iterator it = scene.begin(); it != scene.end() - 1; it++)
{
Shape* s1 = (*it);
Shape* s2 = (*(it + 1));
if (s1->intersects(*s2))
{
delete s1;
delete s2;
// Remove the pointers to s1 and s2 from the vector.
it = scene.erase(it);
it = scene.erase(it);
}
}
}
Seeing as how your code already assumes there are no null pointers in the vector, you can use a null pointer as a marker for deletion, simplifying the logic greatly by separating the marking from the erasing.
for (std::vector<Shape*>::iterator it = scene.begin(); it < scene.end() - 1; ++it)
{
Shape*& s1 = (*it);
Shape*& s2 = (*(it + 1));
if (s1->intersects(*s2))
{
delete s1;
delete s2;
s1 = NULL;
s2 = NULL;
++it;
}
}
scene.erase(std::remove(scene.begin(), scene.end(), NULL), scene.end());
As an aside, your original code could have probably been fixed by changing it != scene.end() - 1
to it < scene.end() - 1
. Because if you end up erasing the last two elements, you'll have an iterator which is equal to scene.end()
, which satisfies the condition it != scene.end() - 1
, and the loop will try to increment it.