我有一个类Circle,我跟踪这些实例:
Circle *f1;
vector<Circle> list;
vector<Circle>::iterator it;
我设法创建了多个圈子并让它们四处移动。如何擦除Circle的特定实例?例如,如果某个圆圈撞到墙壁,则应该擦除它。我已经查看了其他问题,我甚至尝试了他们给出的代码而没有运气。这就是我现在所拥有的:
for (it = list.begin(); it != list.end(); ++it) {
it->x += 1;
if (it->x == ofGetWindowWidth()) {
list.erase(it);
}
}
我已经得到了其他声明来处理if语句,例如颠倒它们的移动方向。 list.erase(它);是我从这里得到的一行代码,我不明白为什么它会崩溃我的程序。
答案 0 :(得分:4)
for (it = list.begin(); it != list.end(); /* nothing here */) {
it->x += 1;
if (it->x == ofGetWindowWidth()) {
it = list.erase(it);
} else {
++it;
}
}
原始代码的问题在于擦除元素会使该元素的迭代器无效 - 您尝试接下来递增的迭代器也是如此。这表现出不确定的行为。
答案 1 :(得分:2)
list.erase使擦除元素的迭代器无效。因此,在擦除“it”指向的元素后,“it”无效,并且在for循环体之后的++ it会导致程序崩溃。 将代码重写为类似于以下内容的代码可以防止崩溃:
for(it=list.begin();it!=list.end(); ) {
//your code
if(it->x==ofGetWindowWidth())
it=list.erase(it);
else
++it;
}
答案 2 :(得分:2)
使用erase()
的上述代码的问题在于,当元素被擦除时,它会使it
的内容无效。您可以使用例如:
for (it = list.begin(); it != list.end(); ) {
it->x += 1;
if (it->x == ofGetWindowWidth()) {
list.erase(it++);
}
else {
++it;
}
}
使用erase()
的分支在it
元素之前将保留的迭代器erase()
移离其当前位置。只有从it++
返回的临时对象才会失效。当然,要使此循环起作用,您不能无条件地增加it
,即非erase()
分支需要自己的增量。
答案 3 :(得分:0)
您可以使用remove_if
进行擦除。这也适用于删除多个元素。在你的情况下它是
list.erase(std::remove_if(list.begin(), list.end(),
[](const Circle& c){return c.x == ofGetWindowWidth();},list.end()),
整数示例:
#include <algorithm>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> str1 = {1,3,5,7};
str1.erase(std::remove_if(str1.begin(), str1.end(),
[](int x){return x<4 && x>2;}), str1.end());
for(auto i : str1) std::cout << i ;
}
打印157