首先看下面的关于删除容器中元素的例子(VS2010中编写):
#include "stdafx.h"
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <list>
int _tmain(int argc, _TCHAR* argv[])
{
std::map<int,std::string> Mymap;
for (int i = 0;i < 10;i++)
{
Mymap.insert(std::make_pair(i,"value"));
}
for (std::map<int,std::string>::iterator iter = Mymap.begin() ;iter != Mymap.end();++iter)
{
std::cout<<"The Value of MyMap at:"<<(*iter).first<<" is "<<(*iter).second<<std::endl;
}
for (std::map<int,std::string>::iterator iter1 = Mymap.begin();iter1 != Mymap.end();)
{
std::cout<<"delete The Value is:"<<(*iter1).first<<std::endl;
Mymap.erase(iter1++);//或者使用iter1 =Mymap.erase(iter1);
}
for (std::map<int,std::string>::iterator iter = Mymap.begin() ;iter != Mymap.end();++iter)
{
std::cout<<"The Value of MyMap at:"<<(*iter).first<<" is "<<(*iter).second<<std::endl;
}
std::vector<int> MyVector;
for (int i =0;i<10;i++ )
{
MyVector.push_back(i);
}
for (std::vector<int>::iterator It = MyVector.begin();It != MyVector.end();++It )
{
std::cout<<"The Value of MyVector is:"<<*It<<std::endl;
}
for (std::vector<int>::iterator It1 = MyVector.begin();It1 != MyVector.end(); )
{
std::cout<<"delete the value is :"<<*It1<<std::endl;
It1 = MyVector.erase(It1);//不能使用MyVector.erase(It1++);
}
std::list<int> MyList;
for (int i = 0;i<10;i++)
{
MyList.push_back(i);
}
for (std::list<int>::iterator listIt = MyList.begin();listIt != MyList.end();++listIt)
{
std::cout<<"the Value of MyList is:"<<*listIt<<std::endl;
}
for (std::list<int>::iterator listIt = MyList.begin();listIt != MyList.end();)
{
std::cout<<"delete the Value of MyList is:"<<*listIt<<std::endl;
listIt = MyList.erase(listIt);//也可以使用MyList.erase(listIt++);
}
return 0;
}
根据上面的代码及注释大家可能会有疑问为什么list和map能用两种方法来删除容器中的元素而vector不能呢?
下面我来介绍一下原因:
首先介绍一下STL中的标准序列容器和标准关联容器
- 标准STL序列容器:vector、string、deque和list。
- 标准STL关联容器:set、multiset、map和multimap。
连续内存容器(也叫做基于数组的容器)在一个或多个(动态分配)的内存块中保存它们的元素。如果一个新元素被查入或者已存元素被删除,其他在同一个内存块的元素就必须向上或者向下移动来为新元素提供空间或者填充原来被删除的元素所占的空间。标准的连续内存容器是vector、string和deque。
基于节点的容器在每个内存块(动态分配)中只保存一个元素。容器元素的插入或删除只影响指向节点的指针,而不是节点自己的内容。所以当有东西插入或删除时,元素值不需要移动。
标准的基于节点的容器为list和set、multiset、map和multimap。
当容器为vector时,由于它是基于连续内存容器,删除其中的一个元素,则后面的元素都要向前移动,所以被删除节点的后面的迭代器全部失效。故MyVector.erase(It1++);中的It1++后指向的迭代器依然为失效状态即未定义状态。所以不能删除。
当容器为map和list的时候,由于他们是基于节点的容器,当删除某一元素的时候,只会引起被删除元素的迭代器失效,后面的迭代器依然有效,故MyList.erase(listIt++)中被删除后的listIt指向有效的迭代器,所以可以删除全部的元素。
综合上面所描述的情况可知。
vector和deque的删除可以使用iter = Mycontainer.erase(iter);
map list set multimap multiset可以使用下面的两种方法删除:
1.iter = Mycontainer.erase(iter);
2.Mycontainer.erase(iter++);
以上为我的拙见,有什么错误请批评指出。