简体   繁体   English

C ++ Vector Iterator:比较和擦除两个元素

[英]C++ Vector Iterator: Compare and Erase Two Elements

I have a std::vector<Shape*> called scene which stores pointers to Shapes. 我有一个名为scene的std::vector<Shape*> ,它存储指向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. 如果s1->intersects(*s2)的返回为真,我需要从向量中删除s1和s2。 The following code isn't correct, I get an exception vector interator is not incrementable . 以下代码不正确,我得到一个异常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 . it != scene.end() - 1 ,您的原始代码可能已经通过更改it != scene.end() - 1来修复it != scene.end() - 1it < 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. 因为如果最终删除最后两个元素,你将拥有一个等于scene.end()的迭代器,它满足条件it != scene.end() - 1 ,并且循环将尝试递增它。

vector iterator becomes invalid when it is erased. 向量迭代器在擦除时变为无效。 you should use vector::erase (iterator first, iterator last); 你应该使用vector :: erase(iterator first,iterator last); to erase multiple objects in the vector at the same time. 同时擦除矢量中的多个对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM