在迭代错误中将对象添加到向量

Adding an object to a vector in the middle of an iteration error

好吧,我正处于循环中,该循环迭代向量中的所有对象:

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 是一个处理从基础 class 继承的派生对象的向量,循环简单地调用该向量中每个对象的 Update() 函数。很简单,一切正常。

然而,当我决定调用 Add() 函数时,它只是将一个新对象添加到向量中,我得到一个异常:

_Myval2 was 0xDDDDDDDD

我知道问题所在:我在派生的 classes 之一的 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 循环中,您不能执行任何修改容器大小的操作。在这种情况下,由于您只是添加元素,因此只需使用传统的基于索引的 for 循环代替,例如:

for (size_t i = 0; i < m_entities.size(); ++i)
{
    auto &itr = m_entities[i];
    itr.second->Update(l_time); // may increase the size of the vector
    if (itr.second->m_isDead)
        Remove(itr.first);
}

或者,如果您不想对添加的新项目调用 Update()

size_t size = m_entities.size();
for (size_t i = 0; i < size; ++i)
{
    auto &itr = m_entities[i];
    itr.second->Update(l_time); // may increase the size of the vector
    if (itr.second->m_isDead)
        Remove(itr.first);
}