【发布时间】:2021-03-19 07:13:33
【问题描述】:
好吧,我正处于一个循环的中间,该循环迭代一个向量中的所有对象:
for (auto &itr : m_entities) {
itr.second->Update(l_time);
if (itr.second->m_isDead)
Remove(itr.first); //don't worry, it does not remove immediately so the vector size wont change
}
m_entities 是一个处理从基类继承的派生对象的向量,循环简单地调用该向量中每个对象的Update() 函数。很简单,一切正常。
但是,当我决定调用 Add() 函数时,它只是将一个新对象添加到向量中,我得到了一个异常:
_Myval2 是 0xDDDDDDDD
我知道问题所在:我在派生类之一的Update() 函数内部调用Add() 函数,这会在仍在进行迭代的同时更改向量的大小。像这样:
for (auto &itr : m_entities) {
itr.second->Update(l_time); //here is where I call "Add," changing the size of the vector
if (itr.second->m_isDead) //and messing everything up
Remove(itr.first);
}
所以我的问题是:如何添加到循环的向量 INSIDE 并且仍然能够完成循环而不会出错?
PS:我需要将它添加到循环中。如果我像使用Remove() 函数那样做,我想要的功能就不起作用。 Remove() 函数仅将实体的 ID 推送到向量中,该向量稍后将从向量中删除。是的,如果我用Add() 函数做类似的事情,它会起作用,但是只要我在循环中添加实体,我就想修改它:
if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
if (...) {
...
//Here it will add to the vector and return the entity ID, which
//I use to find the entity and modify it right away
unsigned int bulletId = m_entityMgr->Add(EntityType::Bullet);
//just a pointer to the newly added entity so I can modify it
Bullet *bullet = (Bullet*)m_entityMgr->Find(bulletId);
... //modifying entity
}
}
然后在它退出这个Update()函数之后,它又回到那个循环并且因为向量的大小被修改而弹出错误。
【问题讨论】:
-
在使用基于范围的
for时,您不能做任何改变容器中元素数量的事情。你invalidate the iterators它被用作簿记。有些容器比其他容器更宽容,但这是vector不太友好的一种情况。 -
有没有办法解决这个问题而不让它失效?
-
你不能只存储
Add/Find产生的那些指针并在之后处理它们(就像你对Remove所做的那样)? -
关于删除代码的战术说明:Look up
std::remove_if。你应该能够让它为你工作。
标签: c++ loops vector containers sfml