1,容器的拷贝
list<string>authors = {"Milton", "Shakspeare", "Austen"};
vector<const char*>articles = {"a" , "an" , "the"};
list<string>list2(authors);
forward_list<string>words(articles.begin(),articles.end());
注:
1,将一个容器初始化另一个容器时,要求两个容器的类型是相同的,并且元素的类型也是相同的
2,当传递迭代器参数来拷贝一个范围时,不要求容器的类型是相同的,只要类型相同就行
2,与顺序容器大小相关的构造函数
vector<int>ivec(10,-1)//10个int元素,每个都初始化为-1
forward_list<int>ivec(10);//10个元素,每个都初始化为0
deque<string>svec(10);//10个元素,每个都是空string
3,标准库array
除了指定容器的大小,还要指定容器的类型
array<int,42>::size_type i ;//类型为:保存42个int的数组
拷贝操作:
int digs[10] = {1,2,3,4,5,6,7,8};
array<int,10>copy = digits;//数组类型匹配就合法
注:
array初始值的类型必须要与创建的容器类型相同,
元素类型和大小也要一样,因为大小是array的一部分
4,在容器的特定位置添加元素
vector<string>svec;
vector<string>slist;
slist.insert(slist.begin(),"hellow!");//等价于调用slist.push_front("Hello!");
svec.insert(svec.begin(),"Hello!");
注:
将元素插入到vector,deque,string的任何位置都是合法的,然而这样做可能很耗时间
在一个位置反复的插入元素
list<string>lst;
auto iter = lst.begin();
while(cin>>word)
iter = lst.insert(iter,word);//等价于调用push_front
5,使用下标访问容器
vector<string>svec;//空vector
cout<<svec.at(0);//抛出一个out_of_range异常
注:
若使用cout<<svec[0];//运行时错误,svec中没有元素!
6,访问元素返回的是引用
if(!c.empty()){
c.front() = 42; //将42赋值c中的第一元素
auto &v = c.back(); //获取指向最后元素的引用
v = 1024; //改变c中的元素
auto v2 = c.back(); //v2不是一个引用,它是c.back()的一个拷贝
v2 = 0; //未改变c中的元素
}
注:
与往常一样,如果我们使用auto变量来保存这些函数的返回值,
并且希望使用此变量来改变元素的值,
必须记得定义为引用类型
7,循环删除list中的所有的奇数
list<int>lst = {1,2,3,4,5,5,};
auto it = lst.begin();
while(it != lst.end())
if( *it % 2 )
it = lst.erase(it);
else
++it;
注:
erase删除元素之后,迭代器返回的位置是删除这个元素的后一个元素
8,删除多个元素
eleml = slist.erase(elem1,elem2);//调用后,elem 1 == elem2
迭代器elem1指向我们要删除的第一个元素,elme2指针向我们要删除的最后一个元素之后的元素
返回指向最后一个被删除元素之后的位置的迭代器
4/27
1,forward_list
添加或删除一个元素是的操作是通过改变给定元素之后的元素来完成的,
这样我们总能访问到被添加和删除操作所影响的元素
forward_list的操作:
insert_after ,emplace_after,erase_after
删除一个元素调用erase_after
before_begin的操作返回首迭代器,这个迭代可以让我们在首元素之前,
在并不存在元素之后添加或删除元素,
使用forward_list实现删除奇数:
forward_list<int>flst = {1,2,3,4,5,6,7};
auto prev = flst.before_begin();//表示flst的首前元素
auto curr = flst.begin()//表示flst中的第一个元素
while (curr != flst.end() ){
if (*curr % 2)
curr = flst.erase_after(prev);//删除他并移动curr
else{
prev = curr;//移动迭代器curr,指向下个元素,prev指向
++curr;
}
}
注:
这里面的curr表示要处理的元素,prev表示curr的前驱,
使用before_begin来初始化prev,他返回之前不存在的元素的迭代器。
当删除奇数时,将prev传递给erase_after,此调用将prev之后的元素删除,
就是删除curr所指向的元素,然后将erase_after的返回值给curr
2,改变容器的大小
使用resize来增大或缩小容器
如果当前的大小大于所要的大小,容器后面的元素会被删除,
如果当前的大小小于新的大小,会将新元素添加到容器后部。
list<int>ilist(10,42)//10个int,每个的值都是42
ilist.resize(15)//将5个值为0的元素添加到ilist的末尾
ilist.resize(25,-1);//将10个值为-1的元素添加到ilist的末尾
ilist.resize(5)//从ilist末尾删除20个元素。
resize只改变容器中元素的数目,而不是容器的容量
3,vector,string,deque中的insert,erase
vector<int>vi = {0,1,2,3,4,5,5};
auto iter = vi.begin();
while (iter != vi.end){
if(*iter % 2){
iter = vi.insert(iter,*iter);
iter += 2;
}
else{
iter = vi.erase(iter);
}
}
注:
我们调用insert和erase后都更新迭代器,因为两者都会使迭代器失效
调用erase后,不必递增迭代器,因为erase返回的迭代器已经指向序列中下一个元素。
调用insert后,需要递增迭代器两次,insert在给定位置之前插入新元素,然后返回指向新插入元素的迭代器,
4,不缓存end返回的迭代器
while(begin != v.end()){
+=begin;
begin = v.insert(begin,42);
+=begin;
}
注:
如果一个循环中插入/删除deque,string,vector中的元素,不要缓存end返回的迭代器
必须每次插入操作重新调佣end();而不能在循环开始前保存他返回的迭代器;
5,capacity和size
vector<int>ivec;
//size为0,capacity的值依赖具体实现,
cout<<"ivec: size"<<ivec.size()<<
"capacity: "<<ivec.capacity()<<endl;
//向ivec添加24个元素
for(vector<int>::size_type ix = 0;ix = 0; ix != 24; ++ ix)
ivec.push_back(ix);
//size应该为24;capacity应该大一等于24,具体值依赖标准库实现
cout<<"ivec : size: "<<ivec.size()
<<"capacity: "<<ivec.capacity()<<endl;
注:
size表示他已经保存的元素的数目
capacity是在不分配新的内存的前提下它最多可以保存多少元素