删除 en 元素后如何正确指向 std::list (双 for 循环)?

发布于 2024-12-24 16:07:55 字数 595 浏览 3 评论 0原文

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

I want to erase an element from the std::list and then point back to this list but when I do it this way

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

}

I got and unhandled exception : iterator is unincrementable

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄情伤 2024-12-31 16:07:55

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

因此您正在执行一个或另一个增量,但绝不会同时执行两者。

I believe the problem is that in some cases (those where you delete an element), you are double incrementing the iterator. Your for loop looks like this:

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

But inside of it you are doing something like this:

jt = l.erase(jt);

So, if the case happens that you do the erase, you erase it and at the same time, set the iterator to the next element... But, you also increment it with the jt++!

The simple approach to fixing this is re-write the for loop slightly to fit this form factor:

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

so you are doing one or the other increments, but never both.

九八野马 2024-12-31 16:07:55

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

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

Erasing an element from a list invalidates iterators that point at that element, but not other iterators. So you need to do the increment before the 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++;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文