从事件的迭代列表中删除元素
Delete element from a iterating list from an event
想知道从事件循环中不断迭代的列表中删除元素的最佳方法是什么。我有一个事件循环,我的列表正在更新
for (auto pIt = this->particles.begin(); pIt != this->particles.end(); pIt++) {
(*pIt)->Update(system, gameTime);
}
在某个基于事件的时间,我必须从列表中删除一个随机元素。它在单独的函数中处理,使用:
this->particles.remove_if([particle](Particle *ptc)->bool {
return ptc == particle;
});
这会导致列表迭代运行时错误,因为循环中的迭代器变得无效。解决这种情况的最佳方法是什么?
我假设元素的删除发生在Update()
函数内部,并且"列表"实际上是std::list
而不是std::vector
。
不要在循环标头中执行pIt++
。相反,请在呼叫Update()
之前pIt++
。 对返回的原始对象调用Update()
:
for (auto pIt = this->particles.begin(); pIt != this->particles.end(); ) {
auto pForCall = *(pIt++);
pForCall->Update(system, gameTime);
}
这不起作用的另一种情况是,当要删除的元素不是我们调用Update
的元素时。
擦除函数必须有权访问循环中使用的迭代器(使其成为成员变量(,如果该迭代器指向要删除的元素,则递增迭代器。这样,您可以防止循环迭代器因擦除而失效。
例:
#include <iostream>
#include <list>
struct Explosion;
struct Particle {
void update(Explosion&);
};
struct Explosion {
std::list<Particle> particles;
std::list<Particle>::iterator particle_iter;
void update() {
for(particle_iter = particles.begin(); particle_iter != particles.end(); ) {
auto to_call = particle_iter++;
to_call->update(*this);
}
}
template<class Condition>
void filter(Condition condition) {
for(auto i = particles.begin(); i != particles.end();) {
auto to_remove = i++;
if(condition(*to_remove)) {
// Remove the element.
if(particle_iter == to_remove)
particle_iter = i;
particles.erase(to_remove);
}
}
}
};
void Particle::update(Explosion& explosion) {
explosion.filter([this](Particle& other) { return this == &other; });
// The above ends up destroying this object.
// Cannot no longer access this and should only return.
}
int main() {
Explosion explosion{{Particle{}, Particle{}}, {}};
std::cout << explosion.particles.size() << 'n';
explosion.update();
std::cout << explosion.particles.size() << 'n';
}
相关文章:
- 如何从存储在std::映射中的std::集中删除元素
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 从矢量中删除元素后出现隔离错误
- 如何使用remove_if从矢量中删除元素
- 如何从使用 for 循环中的矢量大小的矢量中删除元素
- C++映射不删除元素
- 如何从标准::元组中删除元素?
- 在动态数组中添加/删除C++元素
- 如何通过比较彼此的成员从QStringList中删除元素
- 如何修复从矢量中删除元素的错误?
- 从 std::set 中删除元素,同时在 C++17 中迭代该元素
- 使用remove_if从矢量中删除元素
- 用C++从三维矢量中删除元素
- 从对象数组中删除元素
- 如何在不使用 vector::erase() 的情况下编写自定义 Vector 方法来删除元素?
- C++ - 按自定义数据类型向量的值删除元素
- 从任意容器中廉价删除元素的惯用方法?
- 从数组中删除元素不起作用的函数
- 删除元素 BST
- 从向量中删除元素时未处理的异常