类型别名 | |
iterator | 此容器类型的迭代器模式 |
const_iterator | 可以读取元素,但不能修改元素的迭代器类型 |
size_type | 无符号整型类型,足够保存此种容器类型最大可能容器的大小 |
difference_type | 带符号整型类型,足够保存两个迭代器之间的距离 |
value_type | 元素类型 |
reference | 元素的左值类型:与value_type&含义相同 |
const_reference | 元素的const左值类型(即:const value_type&) |
构造函数 | |
C c; | 默认构造函数,构造空容器 |
C c1(c2); | 构造c2的拷贝c1 |
C c(b, e); | 构造c,将迭代器b和e指定范围内的元素拷贝到c(array不支持) |
C c(a, b, c……); | 列表初始化c |
赋值和swap | |
c1 = c2; | 将c1中的元素替换成c2中的元素 |
c1 = {a, b, c……}; | 将c1中的元素替换成列表中元素(不适用array) |
a.swap(b) | 交换a和b的元素 |
swap( a ,b ) | 等价上行 |
大小 | |
c.size() | c中元素数目(不支持forward_list) |
c.max_size() | c可保存最大元素数目 |
c.empty() | 若c中存储了元素,返回false,否则返回true |
添加/删除元素(不适用与array) 注:在不同容器中,这些操作的接口不同 |
|
c.insert(args) | 将args中的元素拷贝进c |
c.emplace(inits) | 使用inits构造c中的一个元素 |
c.erase(args) | 删除args指定的元素 |
c.clear() | 删除c中所有元素,返回void |
关系运算符 | |
==,!= | 所有容器都支持相等(不等)运算符 |
<, <=,>,>= | 关系运算符(无序关联容器不支持) |
获取迭代器 | |
c.begin(), c.end() | 返回指向c的首元素和微元素之后位置的迭代器 |
c.cbegin(),c.cend() | 返回const_interator |
反向容器的额外成员(不支持forward_list) | |
reverse_iterator | 按逆序寻址元素的迭代器 |
const_reverse_iterator | 不能修改元素的逆序迭代器 |
c.rbegin(),c.rend() | 返回指向c首元素和尾元素之前位置的迭代器 |
c.crbegin(),c.crend() | 返回const_reverse_iterator |
迭代器范围
迭代器的元素范围被称为左闭合区间,标准数学描述为 [ begin, end)。表示范围从begin开始,于end之前结束。迭代器begin和end必须指向相同的容器。end可以与begin指向相同的位置,但不能指向begin之前的位置。
- 如果begin与end相等,则范围为空
- 如果begin与end不等,则范围至少包含一个元素,且begin指向该范围中的第一个元素
- 可以对begin递增若干次,使begin==end
while( begin != end)
{
*begin = val;
begin++;
}
容器类型成员
反向迭代器就是一种反向遍历容器的迭代器,即对一个反向迭代器执行++操作,会得到上一个元素。
为了使用容器类型,必须显式使用某类名:
vector<string>::iterator iter;
vector<int>::difference_type count;
begin和end成员
不以c开头的函数都是被重载过的。实际上有两个名为begin的成员:
- 一个是const成员,返回容器的const_iterator类型
- 另一个是非常量成员,返回容器的iterator类型。
当我们对一个非常量对象调用这些成员时,得到的返回iterator版本。只有对const对象低啊用这些函数时,才会得到一个const版本。与const指针和引用类似,可以将一个普通的iterator转换成对应的const_iterator,但反之不行
list<string> a = {"Milton", "Shakespeare", "Austen"};
auto it1 = a.begin(); //lis<string>::iterator
auto it2 = a.rbegin(); //list<string>::reverse_iterator
auto it3 = a.cbegin(); //list<string>::const_iterator
auto it4 = a.crbegin(); //list<string>::const_reverse_iterator
list<string>::iterator it5 = a.begin();
list<string>::const_iterator it6 = a.begin();
//是iterator还是const_iterator依赖于a的类型
auto it7 = a.begin(); //仅当a是const时,it7是const_iterator
auto it8 = a.cbegin(); //it8是const_iterator
容器定义和初始化
C c; | 默认构造函数。如果C是一个array,则c中元素按默认方式初始化,否则c为空 |
C c1(c2); C c1 = c2; |
c1初始化为c2的拷贝。c1和c2必须是相同类型(即,它们必须是相同的容器类型,且保存的是相同的元素类型;对于array类型,两者还必须具有相同的大小) |
C c{a,b,c……}; C c = a,b,c……}; |
c初始化为初始化列表中的元素的拷贝。列表中元素的类型必须与C的元素类型相容。对于array类型,列表中的元素数目必须小于等于array的大小,任何遗漏的元素都进行值初始化 |
C c( b, e ); | c初始化为迭代器b和e指定范围内的元素拷贝。范围中的元素类型必须与C的元素类型相容(array不适用) |
只有顺序容器(不包括array)的构造函数才能接受大小参数 | |
C seq(n); | seq包含n个元素,这些元素进行了值初始化;次构造函数是explicit的(string不适用) |
C seq(n,t); | seq包含n个初始化为值t的元素 |
将一个容器初始化为另一个容器的拷贝
为了创建一个容器为另一个容器的拷贝,两个容器的类型及其元素类型必须匹配。不过,当传递迭代器参数来拷贝一个范围时,就不要求容器类型相同了,且新容器和原容器中的元素类型也可以不同,只要能将要拷贝的元素转换为要初始化的容器的元素类型即可。
list<string> authors = {"Milton", "Shakespeare", "Austen"};
vector<const char *> articles = {"a", "an", "the"};
list<string> list2(authors); //正确:类型匹配
deque<string> authList(authors); //错误:容器类型不匹配
vector<string> words(articles); //错误:容器类型必须匹配
//正确:可以将const char*元素转换为string
forward_list<string> words(articles.begin(), articles.end() );
vector<int> ivec(10, -1);
list<string> svec(10, "hi!");
forward_list<int> ivec(10);
deque<string> svec(10);
array<int, 42> ia1;
array<string, 10> sa1;
赋值和swap
c1 = c2; | 将c1中的元素替换成c2中元素的拷贝。c1和c2必须具有相同的类型 |
c = {a,b,c……} | 将c2中元素替换成初始化列表中元素的拷贝(array不适用) |
swap(c1, c2) c1.swap(c2) |
交换c1和c2中的元素。c1和c2必须具有相同的类型。swap通常比从c2向c1拷贝元素快的多 |
assign操作不适用与关联容器和array | |
seq.assign(b, e) | 将seq中的元素替换成迭代器b和e所表示范围中的元素。迭代器b和e不能指向seq中的元素 |
seq.assign(i1) | 将seq中的元素替换成初始化列表i1中的元素 |
seq.assign(n, t) | 将seq中的元素替换为n个值为t的元素 |
warning:复制相关运算会导致指向左边容器内部的迭代器、引用和指针失效。而swap操作会将容器内容交换,不会导致指向容器的迭代器、引用和指针失效(容器类型为array和string的情况除外)
assign:用于将参数指定的元素(的拷贝)替换左边容器的所有元素
list<sring> names;
vector<const char *> oldstyle;
names = oldstyle; //错误
//正确
names.assign( oldstyle.cbegin(), oldstyle.cend() );
//等价于slist1.clear();
//后跟slist1.insert(slist1.begin(), 10, "Hiya!");
list<string> slist1(1);
slist.assign( 10, "Hiya!");
swap:
- 除array外,swap不对任何元素进行拷贝、删除或插入操作,可以保证在常数时间完成
- swap两个array会真正交互他们的元素。因此,交换两个array所需时间与元素数目成正比
- 与其他容器不同,对一个string调用swap会导致迭代器、引用和指针失效