for条件满足时不会结束

问题描述:

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,就会出错 - “map set iterator not incrementable”。我认为for循环应该在它再次增加之前结束,因为在此之后it!=gameObjects.end()将是错误的。在else语句中添加break可以解决问题。for条件满足时不会结束

没有break,为什么它不起作用?我假设这是迭代器增量时与检查条件时相关的。

你假设正确。迭代器在循环结束时递增,然后检查条件。

所以在打印“itor = end”之后,它会增加到gameObjects.end()++,这当然是无效的。你可以通过检查循环内的itor == gameObjects.end(),然后打破。

编辑:正如在评论中指出的,你最好从循环中删除++,以避免在删除元素后跳过元素。例如:

for(it = gameObjects.begin(); it!=gameObjects.end();) { 
    ... 
    if(it->second->getSprite()->GetPosition().y > 500) { 
     it = Remove(it->second->getName()); 
    } else { 
     ++it; 
    } 
} 
+1

有这里仍然是一个问题。在'it = itor;'和'it ++'之后,你只需跳过一个元素。如果需要连续删除两个,代码将会错过第二个。 – 2012-01-28 15:18:58

+0

@BoPersson好点。我会解决的。 – obmarg 2012-01-28 15:54:14

+0

对不起,但它仍然有点棘手。如果你删除了第一个元素,你就不能减少迭代器(因为它会是=='begin()')。标准是从'for'中移除'it ++',然后*移除一个元素或递增迭代器。 – 2012-01-28 16:03:00

for循环首先执行语句(增加值)然后检查条件。问题在于,for循环尝试在迭代器到达地图末尾后递增迭代器。

std::map<sf::String,VisibleGameObject*>::iterator itor = Remove(it->second->getName()); 
. 
. 
. 
it=itor; 

是你的问题。

在某个时间点的删除语句从gameObjects删除最后一个项目,然后你做it=itor,而不检查您的循环条件这在gameObjects设置到最后一个项目。 for循环在循环结尾增加++,然后您即将超过gameObjects的末尾。

假设你可以出去控制台输出,你可以简化环路一点做,只是做如下:

for(it = gameObjects.begin();it!=gameObjects.end();){ 
    it->second->update(frameTime); 
    it = it->second->getSprite()->GetPosition().y > 500 
     ? Remove(it->second->getName()); 
     : it++; 
} 
+0

谢谢,我不知道在C++中的语法,但我在回复之前尝试了一些沿着这些行的东西 – pighead10 2012-01-28 15:16:19

+0

@PigHead身体的最后一个声明也可能是循环头文件中的地方,正文是一行一行,但我个人发现这比在循环头文件中有这么长的语句更容易阅读 – 2012-01-28 15:20:45