C++ |列表迭代器不可递增

C++ | List iterator not incrementable

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

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

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

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

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

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

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