顺序容器在以下方面都有不同的性能折衷:
1.像容器中添加和删除元素的代价;
2.非顺序访问容器中元素的代价;
原因:容器的存储要么采用数组型,要么链式存储,前者导致不能随机添加删除,后者不能随机访问,
容器的操作集:
iterator 迭代器类型
const iterator 可以读取元素,但不能修改元素的迭代器类型;
size_type 无符号整数类型,该类型的取值范围可以容纳最大容器所保存的元素大小;
value_type元素类型;
reference 元素的左值类型;
const_reference 元素的const 左值类型;
构造函数:
C c;默认构造函数
C c1(c2);拷贝构造函数
C c(b,e);根据迭代器构造c,·
C c{a,b,c}; 列表初始化c;
添加/删除元素
c.insert(args);插入args
c.emplace(inits);插入inits;
c.erase(args);删除args;
c.clear();清空c内所有元素;
c.cbegin(),c.cend();返回const_iterator;
反向容器
reverse_iterator 按逆序寻址元素的迭代器;
const_reverse_iterator不能修改元素的逆序迭代器;
c.rbegin(),c.rend()返回指向尾元素和首元素之前位置的迭代器;
c.crbegin(),c.crend()返回const_reverse_iterator;
反向迭代器:反向遍历容器的迭代器,对一个反向迭代器执行++操作,会得到上一个元素,--操作会得到下一个元素,即以相反的顺序来看待容器;
类型别名:通过类型别名,即使我们不了解容器中元素的类型,我们也可以定义相同类型的变量;
difference_type是一种无符号整型;
begin,end成员
包括cbegin,cend,rbegin,rend;
容器的定义和初始化
拷贝构造函数要求两个变量的容器类型和元素必须相同,列表初始化和迭代器则保持相容就可以了,即允许隐式类型转换;
初始化列表隐含指定了容器的大小;
只有顺序容器的构造函数才接受大小参数,关联容器并不支持;
assign操作
assign:允许隐式类型转换,从相同容器不同但相容的类型元素的赋值;
seq.assign(b,e);将seq中的元素替换为迭代器b,e所表示的范围内的元素;b,e不能指望seq中的元素;
seq.assign(il);将seq内的元素替换为初始化列表il内的元素;
seq.assign(a,t);将seq内的元素替换为a个值为t的元素;
swap:直接交换容器的地址;
swap不对任何元素进行插入删除,拷贝操作,因此swap的操作时间为常数;只是交换了地址;元素不会被移动;但array会真正的交换元素;
容器大小操作:
size:容器内元素的个数;
empty:容器是否为空,
max_size:可容纳的最大大小
关系运算符:
每个容器都支持==,!=,除了无序容器外都支持关系运算符>,<,>=,<=,关系运算符两侧的容器类型和元素类型必须相同,容器的比较实际上进行元素的逐对比较,与string的关系运算符很像:
两个容器大小相同且所有元素对应相等,则相等,否则不等;
两个容器大小不等,但小容器每个元素都等于较大容器内的元素,则小容器小于大容器;
两个容器都不是另一个容器的前缀子序列,比较结果取决于第一个不相等的元素的比较结果;
使用关系运算符的前提是容器内元素类型定义了相应的比较运算符;
顺序容器操作
c.push_bck(t);c.emplace_back(t).在c的尾部创建一个值为t的元素,返回void;
c.push_front(t),c.emplace_front(t)在c的头部创建一个值为t的元素,返回void;
c.insert(p,t)在迭代器p指向的元素之前创建一个置为t的元素,返回指向新添加的元素的迭代器;
c.insert(p,n,t)在迭代器p指向的元素之前创建n个值为t的元素,返回指向新添加的第一个元素的迭代器,若n为0,返回p;
c.insert(p,b,e)将迭代器b,e范围内的元素插入到迭代器p指向的元素之前,b,e不能指向c中的元素,返回新添加的第一个元素的迭代器;若范围为空则返回p;
c.insert(p,il);il是初始化列表,initializer_list<typename>类型的,将这些给定值插入到 p指向的元素之前,返回指向新添加的第一个元素的迭代器;若列表为空,则返回p;
尾插法:push_back()
头插法:push_front():list,deque,forward_list支持该操作,即头插法;
insert
特定位置添加元素:insert(),允许在任意位置插入元素,vector,list,deque,string都提供了该操作;forward_list提供了特殊版本的insert成员,使用insert()可以模拟push_front();
insert有多次重载,插入内容包括特定元素或者某个范围内的元素;
不同于push_back返回void,insert返回的是插入后第一个元素的迭代器值(插入为空时返回原迭代器),因此可以实现反复插入元素;
list<string>lst;
auto iter=lst.begin();
while(cin>>word)
iter=lst.insert(iter,word);
emplace
emplace,使用元素类型的构造函数在容器的某位置直接创建一个元素,其参数类型与类型构造函数参数特征一致,但对于push_back()则是使用临时对象来在容器内插入元素,过后该变量即被释放;即使用了析构函数,可能存在深拷贝,浅拷贝的问题;
c.emplace_back("97805928",25,15);使用这些参数调用构造函数,而后放进容器中;
c.push_back(sales_Data("97805928",25,15));创建临时对象,过后即被销毁,emplace开销更小;
重点:emplace的参数必须与元素类型的构造函数相匹配;
访问元素
c.front(),c.back();获得容器的首尾元素的引用;
访问操作:
c.back,c.front;c[n],c.at(n)
删除元素: