我一直在努力将矢量对象放入我正在做的项目中 我已经阅读了关于这样做的一点点,并决定试一试。
std::vector<BrickFalling> fell;
BrickFalling *f1;
我创建了矢量。下一部分工作正常,直到我得到擦除 部分。
if(brickFall == true){
f1 = new BrickFalling;
f1->getBrickXY(brickfallx,brickfally);
fell.push_back(*f1);
brickFall = false;
}
// Now setup an iterator loop through the vector
vector<BrickFalling>::iterator it;
for( it = fell.begin(); it != fell.end(); ++it ) {
// For each BrickFalling, print out their info
it->printBrickFallingInfo(brick,window,deadBrick);
//This is the part im doing wrong /////
if(deadBrick == true)// if dead brick erase
{
BrickFalling[it].erase;//not sure what im supposed to be doing here
deadBrick = false;
}
}
答案 0 :(得分:4)
您可以使用std::remove_if
和vector::erase
完全避免此问题。
auto it =
std::remove_if(fell.begin(), fell.end(), [&](BrickFalling& b)
{ bool deadBrick = false;
b.printBrickFallingInfo(brick,window,deadBrick);
return deadBrick; });
fell.erase(it, fell.end());
这避免了循环的手写。
通常,您应该努力以这种方式为序列容器编写擦除循环。原因是在自己编写循环时很容易进入“无效迭代器”场景,即每次擦除时都不记得重置循环迭代器。
我不知道的代码唯一问题是printBrickFallingInfo
函数。如果throws
出现异常,则可能会在擦除过程中引入错误。在这种情况下,您可能希望使用try/catch
块保护呼叫,以确保不会过早离开功能块。
编辑:
正如评论所述,您的print...
功能可能只是为了确定砖块是否在下降而做了太多工作。如果你真的想要打印东西并做更多可能导致某种副作用的事情,那么另一种类似的方法就是使用std::stable_partition
。
使用std::stable_partition
,您可以“暂停”删除,只需将要删除的元素移动到容器中的一个位置(在开头或结尾) all,而不会使这些项无效。这是主要区别 - 使用std::stable_partition
,您要做的就是移动要处理的项目,但移动后的项目仍然有效。 std::remove
和std::remove_if
不是这样 - 移动的项目只是无效,任何使用这些项目的尝试都是未定义的行为。
auto it =
std::stable_partition(fell.begin(), fell.end(), [&](BrickFalling& b)
{ bool deadBrick = false;
b.printBrickFallingInfo(brick,window,deadBrick);
return deadBrick; });
// if you need to do something with the moved items besides
// erasing them, you can do so. The moved items start from
// fell.begin() up to the iterator it.
//...
//...
// Now we erase the items since we're done with them
fell.erase(fell.begin(), it);
这里的区别在于我们最终擦除的项目将位于分区迭代器it
的左侧,因此我们的erase()
调用将从中删除项目一开始。除此之外,这些项目仍然是完全有效的条目,因此您可以在最终删除它们之前以任何方式使用它们。
答案 1 :(得分:3)
应尽可能使用详细说明remove_if
使用的其他答案。但是,如果您的情况不允许您使用remove_if
编写代码,这可能发生在更复杂的情况下,您可以使用以下内容:
您可以将vector::erase
与迭代器一起使用以删除该位置的元素。然后使用的迭代器失效。 erase
返回一个指向下一个元素的新迭代器,因此您可以使用该迭代器继续。
你最终得到的是一个循环:
for( it = fell.begin(); it != fell.end(); /* iterator updated in loop */ )
{
if (shouldDelete)
it = fell.erase(it);
else
++it;
}