цикл не заканчивается, когда условие выполнено - PullRequest
0 голосов
/ 28 января 2012
for(it = gameObjects.begin();it!=gameObjects.end();it++){
    it->second->update(frameTime);
    if(it->second->getSprite()->GetPosition().y > 500){
        std::cout << "Removing enemy" << std::endl;
        std::map<sf::String,VisibleGameObject*>::iterator itor = Remove(it->second->getName());
        if(itor!=gameObjects.end()){
            std::cout << "itor doesn't equal" << std::endl;
            it=itor;
        }else{
            std::cout << "itor = end" << std::endl;
            it=itor;
        }
    }
}

Как только печатается itor = end, появляются ошибки - «итератор набора карт не может быть увеличен». Я думал, что цикл for должен завершиться до того, как он снова увеличится, так как it!=gameObjects.end() будет ложным после этого. Добавление break в оператор else решает проблему.

Почему не работает без break? Я предполагаю, что это связано с увеличением итератора по сравнению с проверкой условия.

Ответы [ 4 ]

2 голосов
/ 28 января 2012

for цикл сначала выполняет оператор (увеличивает значение), затем проверяет условие.проблема в том, что цикл for пытается увеличить итератор после того, как он достиг конца карты.

2 голосов
/ 28 января 2012

Вы считаете правильным.Итератор увеличивается в конце цикла, а затем проверяется условие.

Поэтому после вывода «itor = end» он увеличивается до gameObjects.end()++, что, конечно, недопустимо.Вы можете обойти, проверив itor == gameObjects.end() внутри цикла, а затем прервавшись.

РЕДАКТИРОВАТЬ: Как указано в комментариях, лучше просто удалить ++ it из цикла, чтобы избежать пропуска элемента после удаленного элемента.Например:

for( it = gameObjects.begin(); it!=gameObjects.end(); ) {
    ...
    if(it->second->getSprite()->GetPosition().y > 500) {
        it = Remove( it->second->getName() );
    } else {
        ++it;
    }
}
1 голос
/ 28 января 2012

Предполагая, что вы можете обойтись без вывода на консоль, вы можете немного упростить цикл и просто сделать, как показано ниже:

for(it = gameObjects.begin();it!=gameObjects.end();){
    it->second->update(frameTime);
    it = it->second->getSprite()->GetPosition().y > 500 
         ? Remove(it->second->getName()); 
         : it++;
}
1 голос
/ 28 января 2012
std::map<sf::String,VisibleGameObject*>::iterator itor = Remove(it->second->getName());
.
.
.
it=itor;

ваша проблема.

В какой-то момент оператор удаления удаляет последний элемент из gameObjects, а затем вы делаете it=itor, устанавливая его на последний элемент в gameObjects без проверки условия зацикливания. for увеличивает цикл в конце цикла для ++, так что вы находитесь за концом gameObjects.

...