首頁 >後端開發 >C++ >在迭代期間從「std::set」中刪除元素是 C 中定義的行為還是特定於實現的行為?

在迭代期間從「std::set」中刪除元素是 C 中定義的行為還是特定於實現的行為?

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-12-04 08:30:14596瀏覽

Is Deleting Elements from a `std::set` During Iteration Defined Behavior in C   or Implementation-Specific?

在迭代期間從std::set 中刪除元素:實現影響

在刪除元素時迭代集合可能會帶來挑戰,因為操作可能會使迭代器無效。在這種情況下,問題就出現了:這種行為是由 C 標準定義的還是特定於實現的?

實現依賴

根據C 標準(23.1 .2.8),向集合中插入元素不應影響迭代器或對容器的引用,而擦除元素僅應使迭代器和對已刪除元素的參考。然而,在擦除操作期間迭代器的行為並未明確指定,使其對特定於實現的決策開放。

GCC 實作

在提供的範例程式碼中,使用Ubuntu 10.04 上的GCC 4.3.3 在迭代期間從集合中刪除元素不會使迭代器失效。這表明 GCC 的實作遵循更寬鬆的方法,允許在擦除後繼續使用迭代器。

符合解

為了確保標準一致性,採用不同的方法是必須的。一個常見的解決方案是在擦除元素之前建立迭代器的副本:

for (auto it = numbers.begin(); it != numbers.end(); ) {
    if (*it % 2 == 0) {
        numbers.erase(it++);
    }
    else {
        ++it;
    }
}

在這種情況下,後綴增量(it)將舊位置傳遞給erase()函數,同時跳到下一個元素。此處首選後綴增量,因為它避免了前綴增量可能出現的潛在雙增量問題(當條件為 false 時)。

C 11 Update

With C 11 的出現,提供了更優雅的解決方案。現在,erase() 函數傳回一個迭代器,指向最後一個刪除的元素後面的元素(如果最後一個元素被刪除,則傳回 set::end)。這允許更簡潔的實現:

for (auto it = numbers.begin(); it != numbers.end(); ) {
    if (*it % 2 == 0) {
        it = numbers.erase(it);
    }
    else {
        ++it;
    }
}

以上是在迭代期間從「std::set」中刪除元素是 C 中定義的行為還是特定於實現的行為?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn