我对地图的擦除功能的行为感到很困惑。在下面的简单示例中,代码输出“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;
}
答案 0 :(得分:3)
擦除后无法使用迭代器。它无效且行为未确定(崩溃,故障值?):
答案 1 :(得分:0)
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)
中取消引用它是未定义的行为。它实际上与删除指针然后尝试取消引用它相同。
答案 2 :(得分:0)
要删除pre c ++ 11中地图中的元素,您可以使用以下模式:
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()
中也返回了迭代器,但这不符合标准。