![](/img/trans.png)
[英]C++ recursive initialization of vectors using iterators produce inconsistent results
[英]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;
}
刪除之后,您將無法使用迭代器。 它是無效的,無法確定其行為(崩潰,是否有值?):
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.