map.erase(map.end())?

时间:2009-06-04 20:24:07

标签: c++ stl map iterator

考虑:

#include <map>

int main()
{
    std::map< int, int > m;
    m[ 0 ] = 0;
    m[ 1 ] = 1;

    m.erase( 0 );  // ok
    m.erase( 2 );  // no-op
    m.erase( m.find( 2 ) );  // boom!
}

(好吧,所以标题谈到擦除一个end()迭代器,但是find会返回一个不存在的键的end()。)

为什么删除不存在的键OK,但删除end()会爆炸。我在标准中没有看到任何明确的提及?

我在VS2005上尝试了这个(在调试配置中引发异常)和GCC 4.0.1(100%CPU)。它是依赖于实现的吗?

感谢。

4 个答案:

答案 0 :(得分:32)

对于erase(key),标准说明删除了所有带有值键的元素。当然可能没有这样的价值观。

For erase(it)(其中itstd::map::iterator),标准表示其所指向的元素已被删除 - 不幸的是,如果它是end()则不会指向一个有效的元素,你在未定义的行为土地上,就像你使用end()进行任何其他地图操作一样。有关详细信息,请参阅第23.1.2节。

答案 1 :(得分:18)

end()不是地图的交互者。它实际上是“一个接一个结束”的地图。

'iterator'版本想要一个迭代器来映射地图。
擦除的“关键”版本执行查找并保护自己免受未找到的密钥的影响,迭代器版本假设您不打算破解内容。

答案 2 :(得分:3)

而不是上一篇文章中给出的例子......

MapType::iterator it = the_map.find ("new_key");

// Does not exist.
if (it == the_map.end()) {
  the_map.insert (std::make_pair ("new_key", 10));
}

进行两次树遍历,使用...

pair<MapType::iterator, bool> rc = the_map.insert(make_pair("new_key", 0));
if (rc.second)
    rc.first.second = 10;

这样你就可以进行一次树遍历,并且你可以使用迭代器来为其他东西滚动。

答案 3 :(得分:1)

这是一个快速示例,说明在删除时如何使用带有迭代器的STL映射。执行插入时我也会做同样的事情。我个人喜欢使用typedef来专门定义地图,但选择权在你手中。


typedef std::map... MapType;

MapType the_map;

MapType::iterator it = the_map.find ("key");
if (it != the_map.end()) {
  // Do something productive.
  the_map.erase (it);
}

MapType::iterator it = the_map.find ("new_key");

// Does not exist.
if (it == the_map.end()) {
  the_map.insert (std::make_pair ("new_key", 10));
}

希望这有帮助!