9.1 顺序容器概述
名称 |
大小
|
随机访问
|
特点
|
迭代器操作+n,-n、-和关系运算
|
默认构造函数
|
是否支持列表初始化
|
是否支持assign
|
是否支持花括号赋值
|
是否支持大小操作,max_size,empty,size
|
vector |
可变
|
支持
|
尾部之外插入慢
|
都支持
|
支持
|
支持
|
支持
|
支持
|
都支持
|
deque
|
可变
|
支持
|
头尾插入快
|
都支持
|
支持
|
支持
|
支持
|
支持
|
都支持
|
list
|
可变
|
双向顺序
|
任意位置插入快
|
不支持
|
支持
|
支持
|
支持
|
支持
|
不支持size
|
forward_list
|
可变
|
单向顺序
|
任意位置插入快
|
不支持
|
支持
|
支持
|
支持
|
支持
|
都支持
|
array
|
固定
|
支持
|
不能插入删除
|
都支持
|
不支持
|
需要指定大小
|
不支持
|
不支持
|
都支持
|
string
|
可变
|
支持
|
尾部之外插入慢
|
都支持
|
支持
|
支持
|
支持
|
支持
|
都支持
|
确定使用哪种顺序容器
1.最好使用vector
2.如果额外开销很重,不要用list或forward_list
3.如果需要随机访问用vector和deque
4.在头尾插入,不在中间插入用deque
9.2容器库概览
每个容器都定义在一个头文件中,文件名与类型名相同。
9.2.1迭代器
一个迭代器范围为左闭合区间
1.如果begin和end相等则范围为空。
2.如果begin和end不等,则只要包含一个元素。
3.可以对begin递增若干次,使得begin==end
9.2.2 容器类型成员
size_type 保存此容器类型大小
difference_type 有符号整数,足够保存两个迭代器之间距离
value_type 元素类型
reference 元素左值类型,与value_type&含义相同
const_reference 元素的const左值类型
9.2.3 begin和end成员
begin和end生成指向容器第一个元素和尾元素之后位置的迭代器。
9.2.4容器定义和初始化
除array外其他容器的默认构造函数都会创建一个指定类型的空容器。
将一个容器初始化为另外一个容器的拷贝
为创建一个容器为另外一个容器的拷贝,两个容器的类型和元素类型必须匹配。当传递迭代器参数来拷贝一个范围时,就不要求容器类型是相同的了。而且新容器和原容器类型可以不同,只要能将拷贝的元素转换。
list<string> authors = {"Millon","Shakespeare","au"};
vector<const char*> article = {"a","an","the"};
list<string> list2(authors); //正确,类型匹配
deque<string> authList(authors);//错误,容器类型不匹配
vector<string> words(article);//错误:容器类型必须匹配
//正确可以将const char* 转为string
forward_list<string> words(article.begin(),article.end());
当一个容器初始化为另外一个容器的拷贝时,两个容器的容器类型和元素类型都必须相同。
列表初始化
list<string> authors = {"Millon","Shakespeare","au"};
与顺序容器大小相关的构造函数
vector<int> ivec(10,-1);
list<string> svec(10,"hi");
只有顺序容器的构造函数才接受大小参数,关联容器并不支持
标准库array具有固定大小
array的大小是类型的一部分。还要指定array大小。
array<int,10> ia2 = {0,1,2,3};
对array进行列表初始化,初始值的数目必须等于或小于array的大小。
虽然不能对数组进行拷贝和对象赋值,但array并无此限制。
array<int,10> digits = {9,8,7,6};
array<int,10> copy = digits ;//正确
9.2.5 赋值和swap
赋值左右两边运算对象必须具有相同的类型
array<int,10> a2 = {0};//正确
a2 = {0};//错误,不能讲一个花括号列表赋值
array类型不支持assign和不允许用花括号包围的列表赋值。
使用assign
assign允许从一个不同但相容的类型赋值。
list<string> names;
vector<const char*> oldstyle;
names = oldstyle;//错误,类型不匹配
name.assign(oldstyle.cbegin(),oldstyle.cend());//正确
assign的第二个版本,接受一个整型值和一个元素值。
list<string> slist1(1)
slist1.assign(10,"hiya");//10个元素,都是"hiya"
使用swap
swap只是交换两个容器的内部结构,元素本身未交换。
意味着除string外,指向容器的迭代器、引用和指针在swap之后都不会失效。
对string调用swap会导致迭代器、引用和指针失效。
9.3顺序容器操作
名称
| push_back |
emplace_back
|
push_front
|
emplace_front
|
insert
|
front
|
emplace
|
back
|
at和下标操作
| pop_back |
pop_front
|
erase
|
clear
|
resize
|
vector
|
支持
|
支持
|
不支持
|
不支持
|
支持
|
有
|
支持
|
有
|
支持
|
支持
|
不支持
|
支持
|
支持
|
支持
|
deque
|
支持
|
支持
|
支持
|
支持
|
支持
|
有
|
支持
|
有
|
支持
|
支持
|
支持
|
支持
|
支持
|
支持
|
list
|
支持
|
支持
|
支持
|
支持
|
支持
|
有
|
支持
|
有
|
不支持
|
支持
|
支持
|
支持
|
支持
|
支持
|
forward_list
|
不支持
|
不支持
|
支持
|
支持
|
特殊版本
|
有
|
特殊版本
|
无
|
不支持
|
不支持
|
支持
|
特殊版本
|
支持
|
支持
|
array
|
不支持
|
不支持
|
不支持
|
不支持
|
不支持
|
无
|
不支持
|
有
|
支持
|
不支持
|
不支持
|
不支持
|
不支持
|
不支持
|
string
|
支持
|
支持
|
不支持
|
不支持
|
支持
|
有
|
支持
|
有
|
支持
|
支持
|
不支持
|
支持
|
支持
|
支持
|
向vector、string或deque插入元素会导致指向容器的迭代器、引用和指针失效。
insert返回的迭代器正好指向这个新插入的元素
调用emplace成员函数时候,将参数传递给元素类型的构造函数。
at成员函数,如果越界会返回一个out_of_range的异常
erase可以删除一个迭代器指定元素,也可以删除一对迭代器指定范围的所有元素。
forward_list未定义insert、emplace和erase,定义了insert_after、emplace_after和erase_after
容器操作可能让得迭代器失效
向容器添加元素
vector和string存储空间被重新分配,则指向容器的迭代器、指针和引用失效。未重新分配,则插入位置之前的迭代器、指针和引用有效,之后的失效。
deque,插入到首尾位置之外的任何位置都会导致失效。如果在首尾添加元素,迭代器失效,指针和引用不失效。
list和forwardlist,指向迭代器、引用和指针都有效。
删除元素
list和forward_list,指向其他位置的迭代器、指针和引用有效。
deque,首尾之外的任何位置删除元素,迭代器、指针和引用失效,如果删除尾元素,尾后迭代器失效,其他不受影响,删除首元素,都不受影响。
vector和string,被删位置之前的都有效。
9.4vector对象是如何增长
shrink_to_fit 只适用于vector、string和deque
capacity和reserve只适用于vector和string
9.5额外的string操作
string s(s2,pos2) ;//从s2的pos2开始的所有字符
stirng s(s2,pos2,len2) ;//从s2pos2开始len2长度字符
s.substr(pos,n);从pos开始,n个字符拷贝。
s.append(args) ;对s进行追加
s.replace(range,args); 删除range范围内的字符,替换为args
s.find(args) 返回args第一次出现位置
s.rfind(args) 返回最后一次出现位置
s.find_first_of(args) args中的任何一个字符第一次出现位置
s.find_last_of(args) args中任何一个字符最后一次出现的位置
s.find_first_not_of(args) s中第一个不在args的字符
s.find_last_not_of(args) s中最后一个不在args的字符
9.6容器适配器
适配器让一种事物看起来像另外一种事物
stack、queue和priority_queue
每个适配器两个构造函数,一个创建空对象,一个接受容器的构造函数初始化适配器
stack<int> stk(deq);//deq是 dqueue<int>
stack和queue都是基于dqueue实现的。priority_queue是在vector上实现的
statck定义在stack头文件中,queue和priority_queue定义在queue中