2016-03-07 184 views
0

我想遍历一个列表,然后,如果对象的板号与通过参数给出的板号相匹配,并且收费(以收费()计算)小于或等于给定的分,从列表中删除/删除对象。我不断收到列表迭代器不能增加的错误,我对如何解决这个问题毫无头绪。C++ |列表迭代器不可递增

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

取代'它= listLicense.erase(它);''与listLicense.erase(它);' –

+2

(HTTP [未能与GCC重现]:// melpon.org/wandbox/permlink/4ADAdPjUCnV3cthh)。请发布[最小,完整和可验证示例](http://stackoverflow.com/help/mcve)。 – MikeCAT

+0

无法用gcc重现。此外,代码中存在一个错误。如果“if”条件返回true,则会导致未定义的行为。在这种情况下,erase()将返回end(),这将被分配给'it',并且循环迭代再次递增'it'。这是未定义的行为。 –

回答

1

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

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

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

所以,巴里解释说,这是造成失败的说法,问题是,迭代器将试图推进it超越end()这将给未定义的行为。在我的情况下,it只需要一次(仅用于找到与匹配的plate_number),因此它可以在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; 
       } 
     } 
    } 
+1

您第二次冗余地测试'it-> toll()<= cents);和'std :: advance(int,1);'可以被'++ it'替代。 –