使用std :: map :: begin调用std :: map :: erase是否安全?

时间:2013-05-22 07:14:01

标签: c++ map undefined-behavior erase

我们(all)知道,通过迭代器擦除元素,指针使迭代器无效,例如:

std::map< .. > map_;
std::map< .. >::iterator iter;
// ..
map_.erase( iter ); // this will invalidate `iter`.

但是,怎么样:

map_.erase( map_.begin() );

这样安全吗? map_.begin()是否是一个有效的迭代器,指向地图的(新)第一个元素?

“测试它”不是解决方案。

4 个答案:

答案 0 :(得分:3)

begin()不是迭代器,但返回迭代器。擦除第一个元素后,begin()返回另一个(有效)迭代器。

 std::map<int, int> m;
 m[1] = 2;
 m[2] = 3;
 m.erase(m.begin()); // <- begin() points to 1:2
 std::cout << m.begin()->second; // <- begin() points to 2:3 now

答案 1 :(得分:3)

cppreference上,我们看到:

  

所有迭代器(pos,first,last)必须有效且可解除引用,   也就是说,end()迭代器(它是有效的,但不是   dereferencable)不能使用。

这几乎可以回答你的问题。只要begin()的迭代器返回有效可解除引用,就可以在std::map::erase()中使用它。检查begin()是否可以在std::map::erase中使用的好方法是检查它是否等于end()

if(map.begin() != map.end()) {
   map.erase(map.begin());
}

或者,您也可以检查地图是否为空,如果不是,则使用std::map::erase

if(!map.empty()) {
   map.erase(map.begin());
}

答案 2 :(得分:2)

当然是。

map :: begin返回一个有效迭代器,引用地图容器中的第一个元素。 http://www.cplusplus.com/reference/map/map/begin/

注意空地图。

答案 3 :(得分:1)

  

这样安全吗?

是。它使这个对begin()的调用返回的临时迭代器无效,并且在语句结束时销毁了迭代器。

  

map_.begin()是否是一个有效的迭代器,指向地图的(新)第一个元素?

是的,除非地图现在为空。擦除元素不会阻止您为其余元素创建新的迭代器;这将使地图无法使用。