删除循环内的向量元素

arj*_*soh 64 c++ vector erase

我知道这个问题有类似的问题,但我没有设法通过他们的帮助找到我的代码.我只想通过检查循环内该元素的属性来删除/删除向量的元素.我怎样才能做到这一点?我尝试了以下代码,但收到了错误的模糊消息:

'operator ='功能在'播放器'中不可用.

 for (vector<Player>::iterator it = allPlayers.begin(); it != allPlayers.end(); it++)
 {
     if(it->getpMoney()<=0) 
         it = allPlayers.erase(it);
     else 
         ++it;
 }
Run Code Online (Sandbox Code Playgroud)

我该怎么办?

更新:你认为带有指针成员的问题vector :: erase是否属于同一个问题?我需要一个赋值运算符吗?为什么?

Naw*_*waz 117

你不应该itfor循环中增加:

for (vector<Player>::iterator it=allPlayers.begin(); 
                              it!=allPlayers.end(); 
                              /*it++*/) <----------- I commented it.
{

   if(it->getpMoney()<=0) 
      it = allPlayers.erase(it);
  else 
      ++it;
 }
Run Code Online (Sandbox Code Playgroud)

注意评论部分; it++在那里不需要,因为it在身体本身中增加了.

至于错误" 'operator ='函数在"播放​​器"中不可用 ",它来自erase()内部用于operator=移动向量中元素的用法.为了使用erase(),类的对象Player必须是可赋值的,这意味着你需要operator=Player类实现.

无论如何,你应该尽可能地避免原始循环1,而应该更喜欢使用算法.在这种情况下,流行的Erase-Remove Idiom可以简化你正在做的事情.

allPlayers.erase(
    std::remove_if(
        allPlayers.begin(), 
        allPlayers.end(),
        [](Player const & p) { return p.getpMoney() <= 0; }
    ), 
    allPlayers.end()
); 
Run Code Online (Sandbox Code Playgroud)

这是我见过的肖恩家长最好的演讲之一.

  • @TheQuantumPhysicist:是的,这是真的,这就是我这样做的原因:`it = allPlayers.erase(it);`请仔细查看作业!或者随意发布更好的答案. (8认同)

小智 13

if(allPlayers.empty() == false) {
    for(int i = allPlayers.size() - 1; i >= 0; i--) {
        if(allPlayers.at(i).getpMoney() <= 0) {
            allPlayers.erase( allPlayers.begin() + i ); 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我删除向量中元素的方法.这很容易理解,也不需要任何技巧.

  • 快速评论:只需说出(!allPlayers.empty())即可替换(allPlayers.empty()== false).这是因为empty()返回一个布尔类型:如果向量为空,它将返回true.使用"not"运算符就像是说"如果向量为空则不正确".只是为了美化你的代码:) (2认同)

Tim*_*imW 10

忘记循环并使用std或boost范围algorthims.
使用Boost.Range和Lambda它看起来像这样:

boost::remove_if( allPlayers, bind(&Player::getpMoney, _1)<=0 );
Run Code Online (Sandbox Code Playgroud)

  • -1表示不诚实的答案.例如,如何在不知道如何在较低级别执行算法的情况下编写所述算法.不是每个人都可以住在抽象天堂.对于有人试图学习Javascript来回答"USE JQUERY !! 1!"时有用. (30认同)
  • +1.这是[要走的路](http://lazarenko.me/2013/01/14/erasing-vector-the-smart-way/)! (3认同)
  • 仅当您只想删除元素时,此算法才有用。想想场景,`if(condition)it = x.erase(it); 否则{file &lt;&lt; * it; ++; }`。如您所见,如果元素不适合删除时是否要执行其他操作,则不能使用`remove_if`。即使使用它,也可能必须再次遍历循环。 (2认同)

ron*_*nag 5

您的具体问题是您的Player班级没有赋值运算符.您必须使"播放器"可复制或移动,以便将其从矢量中移除.这是因为向量需要是连续的,因此需要重新排序元素以填充删除元素时创建的间隙.

也:

使用std算法

allPlayers.erase(std::remove_if(allPlayers.begin(), allPlayers.end(), [](const Player& player)
{
    return player.getpMoney() <= 0;
}), allPlayers.end());
Run Code Online (Sandbox Code Playgroud)

如果你有提升,甚至更简单:

boost::remove_erase_if(allPlayers, [](const Player& player)
{
    return player.getpMoney() <= 0;
});
Run Code Online (Sandbox Code Playgroud)

如果你不支持C++ 11 lambdas,请参阅TimW的答案.