【问题标题】:Remove element in unordered_set using iterator in a loop在循环中使用迭代器删除 unordered_set 中的元素
【发布时间】:2014-04-23 18:26:44
【问题描述】:

请考虑以下代码:

Class MyClass是自定义类:

class MyClass
{
public:
    MyClass(int v) : Val(v) {}
    int Val;
};

那么下面的代码会在刚刚调用it = T.erase(it);之后导致Debug Assertion Failed进入循环:

unordered_set<MyClass*> T;
unordered_set<MyClass*>::iterator it;

for (int i=0; i<10; i++)
    T.insert(new MyClass(i));

for (it = T.begin(); it != T.end(); it++)
{
    if ( (*it)->Val == 5 )
        it = T.erase(it); // After this line executes, in the next loop, the error occurs.
}

如何解决它,为什么? PS:我的环境:VS2010

【问题讨论】:

  • 如果擦除最后一个元素,则设置it = T.end();,然后执行it++,这是未定义的。

标签: c++ unordered-set


【解决方案1】:

假设最后一个元素的 Val = 5。

it = T.erase(it) 被调用,it 被设置为T.end()

然后调用it++,这会导致错误,因为it 已经设置为结束。

基本上...当您删除当前代码中的一个元素时,您最终会双倍推进迭代器。

你可以用这样的东西代替......

for (it = T.begin(); it != T.end(); (*it)->Val == 5? it = T.erase(it) : ++it)
  ;

【讨论】:

    【解决方案2】:

    这是我通常做的:

    for (auto it = T.begin(); it != T.end(); )
    {
        if ((*it)->value == 5) it = T.erase(it);
        else ++it;
    }
    

    如果您的擦除条件变得更复杂,这可能会增加可读性。

    【讨论】:

      猜你喜欢
      • 2019-11-03
      • 2013-09-01
      • 2020-06-08
      • 2020-03-18
      • 1970-01-01
      • 2013-11-25
      • 1970-01-01
      • 2014-12-16
      • 2019-08-23
      相关资源
      最近更新 更多