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?
This is my way to remove elements in vector. It's easy to understand and doesn't need any tricks.
You should not increment
it
in thefor
loop:Notice the commented part;
it++
is not needed there, asit
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 usesoperator=
to move elements in the vector. In order to useerase()
, the objects of classPlayer
must be assignable, which means you need to implementoperator=
forPlayer
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.
1. It's one of the best talk by Sean Parent that I've ever watched.
Or do the loop backwards.
C++11 has introduced a new collection of functions that will be of use here.
And then you get the advantage of not having to do quite so much shifting of end elements.
Your specific problem is that your
Player
class does not have an assignment operator. You must make "Player" either copyable or movable in order to remove it from a vector. This is due to that vector needs to be contiguous and therefore needs to reorder elements in order to fill gaps created when you remove elements.Also:
Use std algorithm
or even simpler if you have boost:
See TimW's answer if you don't have support for C++11 lambdas.
Late answer, but as having seen inefficient variants:
std::remove
orstd::remove_if
is the way to go.Code for removing elements efficiently:
You might need to write such a loop explicitly e. g. if you need the iterator itself to determine if the element is to be removed (the condition parameter needs to accept a reference to element, remember?), e. g. due to specific relationship to successor/predecessor (if this relationship is equality, though, there is
std::unique
).