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



我们(all)知道,迭代器指针删除元素会使迭代器失效,例如:

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

但是,

map_.erase( map_.begin() );

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

"测试它"不是一个解决方案。

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

在cppreference中,我们看到:

所有迭代器(pos, first, last)必须是有效且可解引用的;也就是说,end()迭代器(有效,但无效)

这基本上回答了你的问题。只要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());
}

当然可以。

map::begin返回指向map容器中第一个元素的有效迭代器。http://www.cplusplus.com/reference/map/map/begin/

注意空地图

这个安全吗?

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

map_.begin()将是一个有效的迭代器,指向映射的(新)第一个元素吗?

可以,除非映射现在是空的。删除一个元素并不会阻止你为剩下的元素创建新的迭代器;这将使地图无法使用。

最新更新