必要说明:
1.关联式容器:map, set
2.顺序式容器:vector,list,deque,forward_list , string
1.节点式(连续内存);vector,deque , string
2,非节点式(非连续内存):map, set,list, forward_list
通常有三条规则:
1. 对于节点式容器(map, list, set)元素的删除,会导致指向该元素的迭代器失效,其他元素迭代器不受影响, 插入操作不会导致迭代器失效
2. 对于非节点式容器(vector,string,deque)元素的删除、插入操作会导致指向该元素以及后面的元素的迭代器失效
3.erase和insert返回的迭代器始终是有效的
//erase返回删除元素的下一个迭代器
//insert返回最后一个添加元素的迭代器,将要插入的元素添加到符合条件元素的前面
删除操作
int main()
{
//vector<int> l{1,2,3,4,3,5};//删除元素后,当前迭代器及以后全失效
list<int> l{1,2,3,4,3,5,3,6};//只有当前迭代器失效
for (auto it = l.begin(); it != l.end();)
{
if(*it == 3)
{
//l.erase(it++);//对list可以,vector不可以,原因是vector删除元素后,当前迭代器及以后全失效,而list只是当前失效
it = l.erase(it);//list和vector都可以,erase都会返回下一个迭代器
}
else
{
++it;
}
}
map<int, string> m{{1, "w"},{2, "r"},{3, "r"}};
for (auto it = m.begin(); it != m.end();)
{
if(it->first == 2)
{
//m.erase(it++);
it = m.erase(it);//map可以
}
else
{
++it;
}
}
return 0;
}
/*
* 总结:
* 删除元素:it = m.erase(it);对所有容器都可以
* m.erase(it++); 仅对节点式(内存不连续)容器有效
* 插入元素:
*/
插入操作:
int main()
{
vector<int> l{1,2,3,4,3,5};
//list<int> l{1,2,3,4,3,5,3,6};//只有当前迭代器失效
for (auto it = l.begin(); it != l.end();++it)
{
if(*it == 3)
{
// l.insert(it, 10);//仅对list有效,会添加到前面,对于vector失效,因为插入后it及以后的iter会失效
it = l.insert(++it,0);// 对list和vector有效,不过会添加到对应元素的后面,函数返回的迭代器始终是有效的
}
}
map<int, string> m{{1, "w"},{2, "r"},{3, "r"}};
for (auto it = m.begin(); it != m.end();++it)
{
if(it->first == 2)
{
m.insert( it,{4, "we"});
//it = m.insert(++it,{4, "we"});//两种map会自动排序
}
}
return 0;
}
/*
* 总结:
* 插入元素:l.insert(it, val);//仅对节点式可以,插入到前面, 对于vector失效,因为插入后it及以后的iter会失效
* it = m.insert(++it,val); 对所有容器都可以,只不过会插入到后面
*/