簡體   English   中英

與C ++中的刪除地圖迭代器不一致的行為

[英]inconsistent behavior with erasing map iterators in C++

我對地圖的擦除功能的行為感到非常困惑。 在下面的簡單示例中,代碼輸出“ 224”。 但是,如果注釋掉“ m ['e'] = 5”行,則會輸出“ 221”。 兩種結果對我來說都沒有意義。 有人可以在這里解釋邏輯嗎?

#include <iostream>
#include <map>
using namespace std;

int main(){

        map<char, int> m;
        m['a'] = 1;
        m['b'] = 2;
        m['c'] = 3;
        m['d'] = 4;
        m['e'] = 5;

        map<char, int>::iterator it = m.begin();        it++; 
        cout << it->second;                             
        m.erase(it); 
        cout << it->second;
        it++;
        cout << it->second << endl;
}

刪除之后,您將無法使用迭代器。 它是無效的,無法確定其行為(崩潰,是否有值?):

http://en.cppreference.com/w/cpp/container/map/erase

map<char, int>::iterator it = m.begin();        it++; 
cout << it->second;                             
m.erase(it);  // (1) 
cout << it->second; // (2)
it++; // (3)
cout << it->second << endl;

您已在位置(1)處使迭代器無效,因此嘗試在(2)(3)取消引用是未定義的行為。 實際上,這等同於刪除指針,然后嘗試取消引用它。

要為c ++ 11之前的版本擦除map中的元素,可以使用以下模式:

for( map_type::iterator it = map.begin(); it != map.end(); ) {
   if( condition_to_erease ) map.erase( it++ );
   else ++i;
}

為什么選擇map.erase( it++ ); 作品? 因為它基本上等效於以下代碼:

map::iterator tmp = it;
++it;
map.erase( tmp );

如果要有效使用C ++,則應了解postfics / prefics運算符的語義。

對於c ++ 11,您還可以使用以下代碼:

for( auto it = map.begin(); it != map.end(); ) {
   if( condition_to_erease ) it = map.erase( it );
   else ++i;
}

我認為在Visual C ++中, std::map::erase()也返回了迭代器,但這不是標准的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM