map在循环时删除时,mm.erase( it++ ) 和 it=mm.erase( it ) 的区别
关于list,vector这类stl在for或者是while循环如果不做处理直接用erase(it)这种是会导致迭代器失效的事,想必已有很多人遇到了。不多解释,现在说一下我遇到的问题。我的代码一般是写两个版本的,跨windows和linux两个平台。在对map进行删除的时候,发现vs2008 it=mm.erase( it )这样是可以的,而在g++下是编译不通过的,这到底是怎么回事,看到网
关于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后该迭代器已立马失效不能再用了。所以需要先将下一个迭代器保存起来。
更多推荐
所有评论(0)