C++ Vector.erase()最后一个元素破坏了迭代器

cel*_*phy 3 c++ iterator vector

我目前遇到vector.erase()的问题.

vector<gameObject> gameObjects;

for (auto it = gameObjects.end() - 1; it != gameObjects.begin();)
    {
        if ((it)->getDestroyed()) {
            it = gameObjects.erase(it);
        }
        else {
            --it;
        }
    }
Run Code Online (Sandbox Code Playgroud)

所以gameObject是游戏中所有内容的基类,它有一个bool标志,基本上告诉我们对象是否被破坏.如果设置了标志,则应从向量中删除该标志.

class gameObject
{
protected:
    bool toBeDestroyed;
public:
    bool getDestroyed();
    void markToDestroy();
};
Run Code Online (Sandbox Code Playgroud)

现在第一个被破坏的对象被成功地从向量中移除然后我得到一个错误:迭代器不是可解除引用的,指向第73行(?)处的向量库.

然后我检查msvc调试器.在数据预览中,它显示迭代器指向gameObjects的最后/最新元素.然后将其删除(擦除(it))并且AFTERWARDS数据预览不会更改,并且调用它 - > getDestroyed()会导致错误消息.

调试断言失败了!矢量迭代器不可解除引用.

PS:我检查了cplusplus.com,vector.erase应该返回一个新的,有效的迭代器,所以我不知道我搞砸了哪里.

€:在我被告知擦除 - 移除成语后,我继续前进,最后得到以下内容,但不能编译.由于我的函数是gameObject的成员,我不知道如何成功调用remove_if.谢谢

gameObjects.erase(remove_if(gameObjects.begin(), gameObjects.end(), gameObject::getDestroyed), gameObjects.end());
Run Code Online (Sandbox Code Playgroud)

€2:很多人指出第一个对象没有被检查.我应该指出这一点,但第一个元素始终是玩家,不应该删除.不过,谢谢你的评论.我会尝试一个简单的前进循环而不会太花哨^^.

€3:我尝试了Jonathan Mees建议的代码,但我得到了完全相同的错误消息.我会试着找出它到底发生了什么但是我不能再把断点放到擦除部分了.会有点乱.

€4:通过删除else {}条件并始终减少迭代器来解决问题.再次感谢您的回复.

Dar*_*con 5

假设你的向量中有2个对象,最后一个被标记为已销毁.当你调用时erase,它将返回一个新的有效迭代器,指向擦除元素后面的元素.擦除元素后没有元素,因此返回的迭代器是gameObjects.end().然后继续到循环的顶部并取消引用此迭代器,这是无效的.如果希望指向有效元素,则需要在擦除后递减迭代器.

另一个注意事项:如果你想要删除你的第一个元素,它就不会.您的循环在迭代器时退出== gameObjects.begin(),因此永远不会检查第一个元素.

有什么理由你想反过来这样做吗?如果没有具体原因,我建议您使用@Borgleader推荐的方法.