【一】vector
删除元素
Std::vector<int> exampleVec = {1,2,3,4,5,6,7};
1. iterator erase( const_iterator pos ) //移除位于 pos 的元素
【注意点】:
(1)迭代器 pos 必须合法且可解引用。所以不能以 end() 迭代器为 pos 的值(合法,但不可解引用),不然会抛异常。
比如:exampleVec.erase(exampleVec.end()); ----->程序向你抛出一个大大的异常,并且崩溃了
2. iterator erase( const_iterator first, const_iterator last ) //移除范围 [first; last) 中的元素
【注意点】:
(1) 若 first==last ,则迭代器 first 不必可解引用:
比如:exampleVec.erase(exampleVec.end(), exampleVec.end()); --->合法的。原因参看下面第2点
(2) 擦除空范围是无操作。
比如:exampleVec.erase(example.begin(),exampleVec.begin()); ---->无任何操作,元素还是1,2,3,4,5,6,7
【返回值】:erase操作的返回值均为最后删除元素的下一个元素的迭代器,如果被删除的元素是最后一个元素,则返回的是end()迭代器。
【删除元素迭代器失效问题】
因为删除元素后,会导致该元素的迭代器失效,所以对vector循环遍历删除某些元素的时候,可能会有迭代器失效问题从而导致程序崩溃。
正确的做法是利用erase的返回值解决问题。下面是正确的示例,该示例演示删除vector中所有的奇数元素。
for (auto beg = exampleVec .begin(); beg != exampleVec .end();) //不是在这里对beg++
{
if (*beg % 2 != 0)
{
beg = exampleVec .erase(beg); //在这里获取下一个元素
}
else
++beg;
}
程序输出:2,4,6
插入元素
1. iterator insert( const_iterator pos, const T& value ); //在 pos 前插入 value
【注意点】:
(1) pos 可为 end() 迭代器
比如: exampleVec.insert( exampleVec.end(),8) --->正确,则现在元素为:1,2,3,4,5,6,7,8
【返回值】:insert操作的返回值都为第一个插入元素的迭代器。
【插入元素迭代器失效问题】
因为插入元素后,后面的元素移动或者当前容量不够存放元素时候进行容量扩展的时候,迭代器会失效,所以对vector循环遍历插入某些元素时候,可能会有迭代器失效问题从而导致程序崩溃。
正确的做法也是利用insert的返回值。下面是正确的示例,该示例演示在vector中所有偶数元素后面插入一个数100。
for (auto beg = vec.begin(); beg != vec.end();++beg)
{
if (*beg % 2 == 0)
{
beg = vec.insert(++beg,100); //如果仅仅写成vec.insert(++beg,100);则程序崩溃
//因为插入后,beg已经失效,再次进入循环时候++beg则异常崩溃
}
}
程序输出:1,2,100,3,4,100,5,6,100,7
总结:关于插入删除迭代器失效的问题,c++11中都使用插入/删除的返回值来获取正确的返回值。以上代码都经过vs2017测试运行。最后吐槽一下,网上好多博客内容都是一本正经的胡说。