【问题标题】:C++ | List iterator not incrementableC++ |列表迭代器不可递增
【发布时间】:2016-03-07 02:57:33
【问题描述】:

我正在尝试遍历一个列表,然后,如果对象的车牌号与通过参数给定的车牌号匹配,并且如果通行费(在 toll() 中计算)小于或等于给定的美分,则删除/从列表中删除对象。我不断收到列表迭代器无法递增的错误,我不知道如何修复它。

void one_time_payment(string& plate_number, int cents) {
    // TODO: REWRITE THIS FUNCTION
    std::list<LicenseTrip>:: iterator it;
    for (it = listLicense.begin(); it != listLicense.end(); std::advance(it, 1)) {
        if (it->plate_number().compare(plate_number) == 0) {
            cout << "Matching Plate Found" << endl;
            if (it->toll() <= cents) {
                cout << "Can be paid" << endl;
                it = listLicense.erase(it); //Error: list iterator cannot be incremented
            }   
        }
    }
    cout << "End of Iterator" << endl;
}

【问题讨论】:

  • listLicense.erase(it);替换it = listLicense.erase(it);
  • 使用 gcc 也无法重现。此外,代码中有一个严重的错误。如果“if”条件返回 true,则会导致未定义的行为。在这种情况下,erase() 将返回 end(),这将被分配给 it,并且循环迭代再次递增 it。这是未定义的行为。
  • 你的代码用 clang 编译得很好

标签: c++ list listiterator


【解决方案1】:

我猜,这不是编译错误,而是触发的断言。你有一个错误!

假设您在最后一个元素上,并且您的所有条件都适用。所以我们这样做:

it = listLicense.erase(it); 

现在,itend()。但紧接着,在 for 循环体的末尾,我们推进it!这是未定义的行为!因此:列表迭代器不能递增。

为了帮助我们正确地写这个,有一个list::remove_if

listLicense.remove_if([&](const LicenseTrip& trip){
    return trip.plate_number() == plate_number &&
        trip.toll() <= cents;
});

【讨论】:

    【解决方案2】:

    因此,正如 Barry 解释的那样,导致断言失败的问题是迭代器会尝试将 it 推进到 end() 之外,这将产生未定义的行为。在我的例子中,it 只需要一次(仅用于定位具有匹配plate_numberLicenseTrip),因此在listLicense.erase(it) 之后放置一个break; 就足够了。最终工作代码如下:

     void one_time_payment(string& plate_number, int cents) {
            std::list<LicenseTrip>:: iterator it;
            for (it = listLicense.begin(); (it != listLicense.end()) ; std::advance(it, 1)) {
                if (it->plate_number().compare(plate_number) == 0 && it->toll() <= cents)
                    if (it->toll() <= cents) {
                        listLicense.erase(it);
                        break;  
                    }
            }
        }
    

    【讨论】:

    • 您第二次重复测试it-&gt;toll() &lt;= cents);并且std::advance(int, 1); 可以替换为++it
    猜你喜欢
    • 2011-09-04
    • 2010-09-16
    • 2010-09-25
    • 1970-01-01
    • 2023-03-03
    • 2013-03-23
    • 1970-01-01
    相关资源
    最近更新 更多