Как правильно указывать обратно на std :: list после удаления элемента en (double for loop)? - PullRequest
0 голосов
/ 05 января 2012

Я хочу стереть элемент из 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 ]

4 голосов
/ 05 января 2012

Я считаю, что проблема в том, что в некоторых случаях (в тех случаях, когда вы удаляете элемент), вы дважды увеличиваете итератор.Ваш цикл 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;
    }
}

, поэтому вы делаете одно или другое приращение, но не оба одновременно.

0 голосов
/ 05 января 2012

Стирание элемента из списка делает недействительными итераторы, которые указывают на этот элемент, но не другие итераторы. Так что вам нужно сделать приращение до стирания:

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++;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...