0

好的,我有一个我正在迭代的引用的 STL 列表。该函数具有三个等效部分。该函数将 wstring 作为参数,并运行适当的 if 语句。我已将代码简化为一个 if 语句以尝试使其正常工作。

因此,我检查了作为参数传入的内容。然后我检查 ClassItem 是否是某种动物。如果是,我检查它是否饿了,然后从列表中删除它。我现在只是想避免段错误,但似乎无法做到。

    list<ClassItem *>::iterator i = Items.begin();

    while(i != Items.end())    
    {
        if(!AnimalType.compare(L"tiger"))
        {
           if((*i)->IsAnimalType(L"tiger"))
           {
              if((*i)->IsHungry())
              {
                  i = Items.erase(i);

              }
           }
           else
           {
              ++i;
           }
        }
      // I have tried removing this
      else
      {
        i++;
      }
    }

我的印象是,当我调用擦除时,当前迭代器无效。所以,如果我删除一个元素,我会返回下一个有效的迭代器。我哪里错了?

编辑:感谢您的所有快速帮助。问题已解决。我使用了phresnel的解决方案,效果很好。

4

3 回答 3

3

最好将std::list::remove_if与合适的谓词一起使用。这完全避免了手动循环,减少了错误的范围,并有助于消除或至少定位问题的根源,因为只要你的谓词是正确的,你就可以相信这个习语是正确的。

bool badAnimal(ClassItem * item) 
{
  // return true if animal is to be removed 
 }

Items.remove_if(badAnimal);
于 2013-10-01T14:16:15.793 回答
1

我认为这里没有段错误的可能性。无论如何:


有(恕我直言)两个可能的问题:

if(!AnimalType.compare(L"tiger"))

这看起来很腥。是什么AnimalType?如果它本身没有您真的期望 的值if(!AnimalType.compare(L"tiger"))在迭代期间发生变化吗?AnimalType

无论如何,它看起来像一个读取,因此不应该写入。它看起来是恒定的,因此不应该改变。


然后:

       if((*i)->IsAnimalType(L"tiger"))
       {
          if((*i)->IsHungry())
          {
              i = Items.erase(i);
          }
          // NO ITERATION IN CASE OF NOT HUNGRY.
          // ONCE TRAPPED HERE, YOU HAVE AN INFINITE LOOP,
          // EXCEPT AnimalType.compare(L"tiger") DOES SOMETHING
          // NON-SANE.
       }
       else
       {
          ++i;
       }

最好是:

       if((*i)->IsAnimalType(L"tiger") && (*i)->IsHungry())
       {
          i = Items.erase(i);
       }
       else
       {
          ++i;
       }

然而,更好的方法是使用标准算法来去除元素。

于 2013-10-01T14:23:11.340 回答
0

你可能想添加

continue;

在你抹去之后。

于 2013-10-01T14:13:29.310 回答