在这种情况下如何擦除矢量元素?

use*_*240 2 c++ iterator vector

我做了一个游戏,rambo射击子弹和子弹击中了僵尸,我想从僵尸矢量中删除被击中的僵尸.

这个嵌套循环逐个检查每个僵尸和子弹之间的冲突.它有效一段时间,但当我开始杀死更多时,它会崩溃,因为它想要使用已删除僵尸的功能.

for ( it = zombies.begin(); it != zombies.end(); ++it ) {
    it->attack();
    for (rambo.it = rambo.bullets.begin(); rambo.it != rambo.bullets.end(); ++rambo.it) {
        if(checkBasicCollision(it,rambo.it) && it != zombies.end()){
            zombies.erase(it);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我现在更好地添加it--;zombies.erase(it);作品,但它有时仍会崩溃.

我认为它的发生就像,例如有5个僵尸和20个子弹,僵尸迭代器是第二个僵尸,第二个僵尸开始子弹循环来检查它是否被击中.循环开始,让第三个子弹击中僵尸,但循环仍在进行,即使僵尸被删除,它仍然继续循环.

我加了休息; 之后zombies.erase(it);它没有任何问题.但代码看起来很脏.有没有其他方法可以轻松擦除当前元素

Mat*_* M. 5

虽然提出了手动擦除的解决方案,但请注意它不是最惯用的解决方案.在惯用的C++中,您可以使用std::remove_if擦除 - 删除习语中的算法,如下所示:

// 1. A predicate that check whether a zombie was it by any bullet:
auto is_zombie_hit = [&rambo](Zombie const& zombie) {
    auto is_bullet_hitting_zombie = [&zombie](Bullet const& bullet) {
        return checkBasicCollision(zombie, bullet);
    };

    return std::any_of(
        rambo.bullets.begin(),
        rambo.bullets.end(),
        is_bullet_hitting_zombie
    );
};

// 2. Use the erase-remove idiom:
zombies.erase(
    std::remove_if(zombies.begin(), zombies.end(), is_zombie_hit),
    zombies.end()
);
Run Code Online (Sandbox Code Playgroud)

注意:是的,您可以就地使用lambda,但我更喜欢命名它们来表明它们的作用.

注意:这使用C++ 11,但是用谓词替换lambda是微不足道的,并且any_of很容易生成,就像all_ofnone_of.