векторный итератор не разыменовывается при удалении из вектора C ++ - PullRequest
0 голосов
/ 19 мая 2018

У меня есть вектор с большим количеством элементов, которые создаются и удаляются непрерывно.
Я хочу поменять элемент, который должен быть удален, на последний элемент, а затем использовать pop_back(), чтобы избежать удаления в серединевектора, но я всегда получаю, что мой итератор не разыменовывается, и я не совсем понимаю, почему это проблема.

Может кто-нибудь объяснить, что именно происходит?

void EntityManager::RemoveEntity(Entity* entity)
{
    std::vector<Entity*>::iterator it = std::find(mEntities.begin(), mEntities.end(), entity);

    if (it != mEntities.end())
    {
        int pos = it - mEntities.begin() + 1;
        std::iter_swap(mEntities.begin() + pos, mEntities.end()-1);
    }
        mEntities.pop_back();
}

Ответы [ 2 ]

0 голосов
/ 19 мая 2018

find возвращает итератор, который указывает на найденный элемент, который (в вашем случае) является элементом, который вы хотите удалить.Когда вы вычисляете pos, вы получаете индекс для элемента сразу после того, который был найден.Если найденный элемент является последним элементом в векторе, это будет ссылаться на элемент one-past-the-end.Когда вы затем вычислите итератор для этого, вы получите итератор end, который вы не можете разыменовать.

Вам не нужно вычислять индекс.Просто позвоните

std::swap(*it, m_Entities.back());

, а затем немедленно позвоните mEneities.pop_back() в теле if, а не после.При вызове pop_back за пределами if вы удалите последний элемент вектора, если искомый элемент не был найден.

0 голосов
/ 19 мая 2018

Эта часть:

int pos = it - mEntities.begin() + 1;

не нужна.Все, что вам нужно сделать, это:

if (it != mEntities.end())
    std::iter_swap(it, mEntities.end() - 1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...