stl陷阱

术语

序列式容器:
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的头或尾删除元素时,只有指向该元素的迭代器失效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值