术语
序列式容器:
vector 、deque 、list 是序列式容器
关联式容器:
map 、 set 、 multimap 、 mutiset 是关联式容器
顺序式容器:
vector、deque容器其内部数据结构是一个数组, 可理解为是顺序式容器;
节点式容器:
相反的, map 、 set 、 multimap 、 mutiset 是节点式容器。
erase函数:
特殊关注点
erase(iter)后, iter肯定是不能在用了,原因就是: 类似野指针问题。
所以earse(iter++)可以, earse(++iter)不可以。
注意
因为顺序存储的容器一旦erase时,会涉及到数据移动,iterator所指的位置还是那个位置,但元素却移动了,iter++之后已不再你想要的元素位置了。
所以 vec.erase(iter++); 会带来未知的问题, 不可以这样写。
返回值C++98和C++11 区别
返回下一个元素的迭代器。
节点式容器
在C++98时, erase(iter++)返回值是void,所以不允许 iter = map.erase(iter);
但在C++11, 支持了 iter = map.erase(iter), 也可以返回下一个元素的迭代器了。
顺序式容器
C++98和C++11没区别。
总结
1.对于节点式容器
std::list<struct> mList;
...
std::list<struct>::iterator iter = mList.begin();
for ( ; iter != mList.end(); )
{
if (...)
{
//因为节点式只会导致当前节点迭代器失效,所以删除节点的同时对迭代器进行后移的操作,因为其他元素不会失效
mList.erase(iter++);// i++ 返回原来的值,++i 返回加1后的值。
/* or //C++11也可以这样
iter = mList.erase(iter);
*/
}
else
{
++iter;
}
}
2.对于顺序式容器
std::vector<struct> mVector;
...
std::vector<struct>::iterator iter = mVector.begin();
for ( ; iter != mVector.end(); )
{
if (...)
{
//这里顺序式容器的erase()会返回紧随被删除元素的下一个元素的有效迭代器
iter = mVector.erase(iter);
}
else
{
++iter;
}
}
其他:
vector:
vector的迭代器在内存重新分配时将失效, 即当超过容量时: 当把超过capacity()-size()个元素插入vector中时,内存会重新分配,所有的迭代器都将失效
未超过容量时:
当添加元素时, 指向当前元素以后的任何元素的迭代器都将失效。
当删除元素时,指向被删除元素以后的任何元素的迭代器都将失效。
deque:
增加任何元素都将使deque的迭代器失效。在deque的中间删除元素将使迭代器失效。在deque的头或尾删除元素时,只有指向该元素的迭代器失效。