关于list,vector这类stl在for或者是while循环如果不做处理直接用erase(it)这种是会导致迭代器失效的事,想必已有很多人遇到了。不多解释,现在说一下我遇到的问题。

我的代码一般是写两个版本的,跨windows和linux两个平台。在对map进行删除的时候,发现vs2008  it=mm.erase( it )这样是可以的,而在g++下是编译不通过的,这到底是怎么回事,看到网上大把大把的it=mm.erase( it )操作,我想说,难道是我g++版本不对么。可是,搜索发现也有其他人遇到和我一样的问题,反正无事,就深究一下好了。

 

这个是我从vs2008 的 map头文件中复制出来的erase函数的声明,可以看到,map的erase函数参数为迭代器的第一个和第三个返回值是void类型。

 void erase(const_iterator _Where)
  { // erase element at _Where
  _Mybase::erase(_Where);
  }

 size_type erase(const key_type& _Keyval)
  { // erase and count all that match _Keyval
  return (_Mybase::erase(_Keyval));
  }

 void erase(const_iterator _First, const_iterator _Last)
  { // erase [_First, _Last)
  _Mybase::erase(_First, _Last);
  }

 

这个是我从msdn上map复制下来的。

iterator erase(
   iterator _Where
);
iterator erase(
   iterator _First,
   iterator _Last
);
size_type erase(
   const key_type& _Key
);

 

看到这里,我有些郁闷,到底哪个是对的。好吧,终于让我在那一片莫名其妙的英语中,终于让我看到这一段

 Return Value

For the first two member functions, a bidirectional iterator that designates the first element remaining beyond any elements removed, or a pointer to the end of the map if no such element exists.

Note:

This return type does not conform to the C++ standard.

For the third member function, returns the number of elements that have been removed from the map.

Remarks

In some instances, this method might throw an out_of_range exception. This behavior does not conform to the C++ standard.

 

看到我描红的那两句了么,我吐血了。 map.erase的返回值,微软进行了修改,可能是为了和list,vector这些容器统一吧。但是C++标准里map.erase参数为迭代器的返回值是void。所以,如果想要更好的跨平台,使用map迭代器做删除操作时,应选择mm.erase( it++ )这种方式,在vs2008 以及DEV C++中测试通过。

另外,可以使用下面这种替代方式,额,很麻烦的说。

   map<int, int>::iterator tt=it;
   tt++;
  mm.erase(it);
   it = tt;

 

千万不要

   map<int, int>::iterator tt=it;
  mm.erase(it);
   it = ++tt;

会出现段错误,可见map在调用earse后该迭代器已立马失效不能再用了。所以需要先将下一个迭代器保存起来。

 

 

 

 

Logo

更多推荐