c++vectorerase

Remove elements of a vector inside the loop


I know that there are similar questions to this one, but I didn’t manage to find the way on my code by their aid. I want merely to delete/remove an element of a vector by checking an attribute of this element inside a loop. How can I do that? I tried the following code but I receive the vague message of error:

'operator =' function is unavailable in 'Player’.

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

What should I do?

Update: Do you think that the question vector::erase with pointer member pertains to the same problem? Do I need hence an assignment operator? Why?


Solution

  • You should not increment it in the for loop:

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

    Notice the commented part;it++ is not needed there, as it is getting incremented in the for-body itself.

    As for the error "'operator =' function is unavailable in 'Player’", it comes from the usage of erase() which internally uses operator= to move elements in the vector. In order to use erase(), the objects of class Player must be assignable, which means you need to implement operator= for Player class.

    Anyway, you should avoid raw loop1 as much as possible and should prefer to use algorithms instead. In this case, the popular Erase-Remove Idiom can simplify what you're doing.

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

    1. It's one of the best talks by Sean Parent that I've ever watched.