按位置删除向量中的元素?

时间:2016-03-28 22:53:56

标签: c++ sdl stdvector

在我的课程中,我尝试使用std::vector循环从for中删除元素。但是,当我尝试删除元素时,我收到一个错误,我不太确定如何解决它。我得到的错误是:

  

错误4错误C2679:二进制' +' :没有找到哪个操作符采用类型' Enemy *'的右手操作数。 (或者没有可接受的转换)

void Enemy::UpdateEnemies(SDL_Renderer * render)
{
    for (int i = enemies.size() - 1; i >= 0; i--)
    {
        enemies[i]->Update();
        if (enemies[i]->Active == false)
        {
            // Receive the error here
            enemies.erase(enemies.begin() + enemies.at(i));             
        }
    }
    if ((SDL_GetTicks()-prevSpawnTime)/1000.0f > enemySpawnTime)
    {
        prevSpawnTime = SDL_GetTicks();
        //Add an anemy
        AddEnemy(render);
    }    
}

4 个答案:

答案 0 :(得分:1)

假设您要删除i个元素,则需要执行

enemies.erase(enemies.begin() + i);

或更好

enemies.erase(std::next(enemies.begin(), i));

在你的情况下,enemies.at(i)返回位置i的解除引用的迭代器,即Enemy类型的元素,而不是i或位置{{1}的迭代器}。

更好的方法是使用反向迭代器:

i

答案 1 :(得分:1)

其他答案给了你天真的解决方案。但是,如果要移除多个敌人,则需要更好的解决方案。

在这种情况下,使用melt中的FUN会更好。这样可以避免对向量中的项目进行重复洗牌。它的工作原理是将您要删除的所有内容移动到容器的 end ,然后为它们的开头提供一个迭代器。

std::remove_if

在这种情况下,您必须先更新所有敌人。如果不需要以相反的顺序完成,那么:

<algorithm>

答案 2 :(得分:0)

这一行:

enemies.erase(enemies.begin() + enemies.at(i));
  • enemise.at(i)返回存储在向量中的敌人。
  • enemies.begin()是一个指针

正如错误所示,您正在尝试添加指针和向量。

您可能只想致电:

enemies.erase(enemies.begin() + i);

答案 3 :(得分:0)

除了其他人所说的,我还会更进一步,并建议从循环内的向量中擦除可能会导致未定义的行为。我没有看到休息,所以我认为可能有多个不活跃的敌人。不要编写自己的循环,而应考虑使用std :: remove_if算法。本质上,您的代码是尝试使用无法编译的对象引用添加迭代器。 remove_if解决方案基本上将Active == false的所有敌人复制到容器的末尾,同时将其他所有内容向前移动。它提供了一种方便的方法来首先识别要删除的内容,然后立即将它们全部删除。此外,如果您没有C ++ 11编译器,如果您使用不同类型的谓词,则同样的事情将起作用。 remove_if链接包含一个函数示例,但您也可以使用函子。

enemies.erase(std::remove_if(enemies.begin(), enemies.end(), [](const Enemy* e){ return e->Active == false; }), enemies.end());

有关详细信息,请查看这些内容。

What is a lambda expression in C++11?

http://www.cplusplus.com/reference/algorithm/remove_if/

C++ Functors - and their uses