如何在删除一个元素(double for循环)后正确地指向std::list

How to properly point back to std::list after erasing en element (double for loop)?

本文关键字:正确地 循环 list std for 元素 删除 一个 double      更新时间:2023-10-16

我想从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

我认为问题在于在某些情况下(删除元素的情况下),您对迭代器进行了双加。你的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;
    }
}

所以你只能做其中一个增量,而不能同时做。

从列表中删除一个元素会使指向该元素的迭代器失效,但不会使指向其他元素的迭代器失效。所以你需要在erase前进行增量操作:

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++;
        }
    }
}