我知道这个问题有类似问题,但我没有设法通过他们的帮助找到我的代码。我只想通过检查循环内该元素的属性来删除/删除向量的元素。我怎样才能做到这一点?我尝试了以下代码,但收到了错误的模糊消息:
'operator ='功能在'播放器'中不可用。
for (vector<Player>::iterator it = allPlayers.begin(); it != allPlayers.end(); it++)
{
if(it->getpMoney()<=0)
it = allPlayers.erase(it);
else
++it;
}
我该怎么办?
更新:您认为问题vector::erase with pointer member是否属于同一问题?我需要一个赋值运算符吗?为什么?
答案 0 :(得分:112)
您不应在it
循环中增加for
:
for (vector<Player>::iterator it=allPlayers.begin();
it!=allPlayers.end();
/*it++*/) <----------- I commented it.
{
if(it->getpMoney()<=0)
it = allPlayers.erase(it);
else
++it;
}
注意注释部分;那里不需要it++
,因为it
在for-body本身中会增加。
对于错误“'operator ='函数在'播放器'中不可用”,它来自erase()
的使用,它在内部使用operator=
来移动元素在向量中。要使用erase()
,类Player
的对象必须是可分配的,这意味着您需要为operator=
类实现Player
。
无论如何,你应该尽可能避免使用raw loop 1 ,而应该更喜欢使用算法。在这种情况下,流行的Erase-Remove Idiom可以简化您正在做的事情。
allPlayers.erase(
std::remove_if(
allPlayers.begin(),
allPlayers.end(),
[](Player const & p) { return p.getpMoney() <= 0; }
),
allPlayers.end()
);
1。这是我曾经看过的the best talk by Sean Parent之一。
答案 1 :(得分:12)
if(allPlayers.empty() == false) {
for(int i = allPlayers.size() - 1; i >= 0; i--) {
if(allPlayers.at(i).getpMoney() <= 0) {
allPlayers.erase( allPlayers.begin() + i );
}
}
}
这是我删除vector中元素的方法。 这很容易理解,也不需要任何技巧。
答案 2 :(得分:11)
忘记循环并使用std或boost范围算法。
boost::remove_if( allPlayers, bind(&Player::getpMoney, _1)<=0 );
答案 3 :(得分:5)
您的具体问题是您的Player
类没有赋值运算符。您必须使“播放器”可复制或移动,以便将其从矢量中移除。这是因为向量需要是连续的,因此需要重新排序元素以填充删除元素时创建的间隙。
此外:
使用标准算法
allPlayers.erase(std::remove_if(allPlayers.begin(), allPlayers.end(), [](const Player& player)
{
return player.getpMoney() <= 0;
}), allPlayers.end());
如果你有提升,甚至更简单:
boost::remove_erase_if(allPlayers, [](const Player& player)
{
return player.getpMoney() <= 0;
});
如果你不支持C ++ 11 lambdas,请参阅TimW的答案。
答案 4 :(得分:4)
或者向后循环。
for (vector<Player>::iterator it = allPlayers.end() - 1; it != allPlayers.begin() - 1; it--)
if(it->getpMoney()<=0)
it = allPlayers.erase(it);
答案 5 :(得分:3)
C ++ 11引入了一个新的函数集合,将在这里使用。
allPlayers.erase(
std::remove_if(allPlayers.begin(), allPlayers.end(),
[](auto& x) {return x->getpMoney() <= 0;} ),
allPlayers.end());
然后你可以获得不必进行相当多的终端元素移动的优势。