如何在擦除en元素(double for循环)后正确指回std :: list?

时间:2012-01-04 22:58:11

标签: c++ iterator unhandled-exception erase stdlist

我想从std::list中删除一个元素然后再回到此列表但是当我这样做时

for(std::list<CvRect>::iterator it = listOfCvRects.begin(); it != listOfCvRects.end(); it++)
{
    for(std::list<CvRect>::iterator jt = listOfCvRects.begin();  jt != listOfCvRects.end(); jt++)
    {
        if( it == jt )
        { continue;}

        if( (jt->x) > (it->x) //.. more conditions...)
        {
            jt = listOfCvRects.erase(jt);
            //OR 
            //listOfCvRects.erase(jt++);
        }
    }

}

我得到了未处理的异常:iterator is unincrementable

2 个答案:

答案 0 :(得分:4)

我认为问题在于,在某些情况下(删除元素的那些情况),您需要对迭代器进行双倍递增。你的for循环看起来像这样:

for(std::list<T>::iterator jt = l.begin();  jt != l.end(); jt++) {
    ....
}

但在其中你正在做这样的事情:

jt = l.erase(jt);

所以,如果你发生擦除的情况,你擦除它,同时将迭代器设置为下一个元素......但是,你也用jt++递增它!

解决这个问题的简单方法是稍微重写for循环以适应这种形状因素:

for(std::list<T>::iterator it = l.begin(); it != l.end(); ) { // notice no increment!
    // ...
    if(cond) {
        it = l.erase(it);
    } else {
        ++it;
    }
}

所以你要做一个或另一个增量,但不要两个。

答案 1 :(得分:0)

从列表中删除元素会使指向该元素的迭代器无效,但不会使其他迭代器失效。所以你需要在擦除之前做增量:

for(std::list<CvRect>::iterator it = listOfCvRects.begin(); it != listOfCvRects.end(); it++) {
    std::list<CvRect>::iterator jt = listOfCvRects.begin();
    while (jt != listOfCvRects.end()) {
        if( it == jt) continue;
        if( (jt->x) > (it->x) //.. more conditions...) {
            listOfCvRects.erase(jt++);
        } else {
            jt++;
        }
    }
}