向量迭代器在2 for for循环中擦除向量元素时可递增

时间:2014-04-18 15:06:36

标签: c++ vector stl iterator erase

我目前正在使用2D地图为控制台编写一个小游戏。我游戏的两个要素是:摧毁战场和敌人,它们随机扩散(越来越大)。这两个"实体"保存在包含两个向量(X和Y)的结构中。我现在正试图删除" _Enemy"(< -private类结构中的实例,与#34; _DestroyedFields&#34相同;)如果你摧毁敌人所在的领域。

我尝试了很多不同的变体来做到这一点,并且给我的错误最少的是这种方法(我已经在互联网上搜索了一段时间,但现在找不到我的问题的答案):

for (std::vector<int>::iterator itEX = _Enemys.X.begin(), itEY = _Enemys.Y.begin();
     itEX != _Enemys.X.end() && itEY != _Enemys.Y.end();
     ++itEX, ++itEY) {
  for (std::vector<int>::iterator itX = _DestroyedFields.X.begin(), 
                                      itY = _DestroyedFields.Y.begin(); 
           itX != _DestroyedFields.X.end() && itY != _DestroyedFields.Y.end(); 
           ++itX, ++itY) {
    if (*itY == *itEY && *itX == *itEX){
        itEY = _Enemys.Y.erase(itEY);
        itEX = _Enemys.X.erase(itEX);
    }
  }
}

PS:对不起,如果我的英语不是最好的,我是德国人^^

PSS:如果你想看看我的整个代码,你可以在Github上找到它:https://github.com/Aemmel/ConsoleGame1

3 个答案:

答案 0 :(得分:2)

使用迭代器it删除后,由于it无效,因此无法进一步使用it。您应该使用调用的结果来擦除哪个是新的有效迭代器。

for( it = v.begin(); it != v.end();)
{
   //...   
   if(...)
   {
      it = v.erase( it); 
   }
   else
   {
      ++it;
   }
   ...
}

答案 1 :(得分:0)

我首先解决了这个问题:制作一个&#34;简单的结构&#34;(struct Entity {int X; intY}然后std :: vector [在这里插入名称])然后添加一个中断;如果条件成立。

for (Uint itE = 0; itE < _Enemys.size(); ++itE){
        for (Uint it = 0; it<_DestroyedFields.size(); ++it){
            if (_Enemys.at(itE).Y == _DestroyedFields.at(it).Y 
                && _Enemys.at(itE).X == _DestroyedFields.at(it).X){
                _Enemys.erase(_Enemys.begin()+itE);
                break;
            }
        }
    }

答案 2 :(得分:0)

使用struct Position {int x; int y;};和一些公用事业运营商,
您可以执行以下操作之一:(https://ideone.com/0aiih0

void filter(std::vector<Position>& positions, const std::vector<Position>& destroyedFields)
{
    for (std::vector<Position>::iterator it = positions.begin(); it != positions.end(); ) {
        if (std::find(destroyedFields.begin(), destroyedFields.end(), *it) != destroyedFields.end()) {
            it = positions.erase(it);
        } else {
            ++it;
        }
    }
}

或者,如果输入已排序,您可以使用“差异”:

std::vector<Position> filter2(const std::vector<Position>& positions, const std::vector<Position>& destroyedFields)
{
    std::vector<Position> res;
    std::set_difference(positions.begin(), positions.end(),
                        destroyedFields.begin(), destroyedFields.end(),
                        std::back_inserter(res));
    return res;
}