4

请考虑以下代码:

Class MyClass是一个自定义类:

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

然后以下代码将Debug Assertion Failed在调用后立即进入循环it = T.erase(it);

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

4

2 回答 2

4

假设最后一个元素的 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)
  ;
于 2014-04-23T18:36:28.997 回答
3

这是我通常做的:

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

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

于 2017-03-22T14:44:10.613 回答