2016-03-07 191 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'替代。 –