顺序容器
容器库概览
迭代器
与容器一样,迭代器有着公共的接口:如果一个迭代器提供某个操作,那么所有提供相同操作的迭代器对这个操作的实现方式都是相同的。
迭代器范围
一个迭代器范围是由一对迭代器表示,两个迭代器分别指向同一个容器中的元素或者尾元素之后的位置。这两个迭代器通常被称为 begin 和 end,或者 first 和 last
这种元素范围被称为左闭合区间 [begin, end)
使用左闭合范围的编程假定
容器类型成员
反向迭代器是一种反向遍历容器的迭代器,与正向迭代器相比,各种操作的含义都发生了跌倒
例如:对一个反向迭代器执行++操作,会得到上一个元素
begin 和 end 成员
带 r 的版本返回反向迭代器,以 c 开头的版本返回 const 迭代器
与 const 指针和引用类似,可以将一个普通的 iterator 转换成对应的 const_iterator,但反之则不行
当不需要写访问时,应使用 cbegin 和 cend
容器定义和初始化
每个容器类型都定义了一个默认构造函数。除 array 之外,其他容器的默认构造函数都会创建一个指定类型的空容器,且都可以接受指定容器大小和元素初始值的参数
将一个容器初始化为另一个容器的拷贝
直接拷贝整个容器,或者(array除外)拷贝由一个迭代器对指定的元素范围
标准库 array 具有固定大小
由于大小是 array 类型的一部分,array 不支持普通的容器构造函数。这些构造函数都会确定容器的大小,隐式或显式
一个默认构造的 array 是非空的,它包含了与其大小一样多的元素。这些元素都被默认初始化,就像一个内置数组中的元素那样
赋值和 swap
赋值运算符将其左边容器中的全部元素替换成右边容器中元素的拷贝
第一个赋值运算后,左边容器将于右边容器相等。如果两个容器原来大小不同,赋值运算后两者的大小都与右边容器的大小相同。第二个赋值运算后,c1 的 size 变成 3
与内置数组不同,标准库 array 类型允许赋值。赋值号左右两边的运算对象必须具有相同的类型
由于右边运算对象的大小可能与左边运算对象的大小不同,因此 array 类型不支持 assign,也不允许用花括号包围的值列表进行赋值
使用 assign (仅顺序容器)
赋值运算符要求左边和右边的运算对象具有相同的类型。它将右边运算对象中所有元素拷贝到左边运算对象中。顺序容器(array 除外)还定义了一个 assign 的成员,允许我们从一个不同但是相容的类型赋值,或者从容器的一个子序列赋值。assign 操作用参数指定的元素(的拷贝)替换左边容器中的所有元素。
使用 swap
swap 操作交换两个相同类型容器的内容。调用 swap 之后,两个容器中的元素将会交换:
除 array 外,swap 不对任何元素进行拷贝,删除或插入操作,因此可以保证在常数时间内完成
元素不会移动意味着,除 string 外,指向容器的迭代器,引用和指针在 swap 操作之后都不会失效。它们仍指向 swap 操作之前所指向的那些元素。但是,在 swap 之后,这些元素已经属于不同的容器了
与其他容器不同,swap 两个 array 会真正交换它们的元素,因此,交换两个 array 所需的时间与 array中元素的数目成正比
容器大小操作
关系运算符
比较两个容器实际上是进行元素的逐对比较,这些运算符的工作方式与 string 的关系运算符类似
容器的关系运算符使用元素的关系运算符完成比较
只有当其元素类型也定义了相应的比较运算符时,我们才可以使用关系运算符来比较两个容器
顺序容器操作
向顺序容器添加元素
不同容器使用不同的策略来分配元素空间,而这些策略会影响性能。在一个 vector 或 string 的尾部之外的任何位置,或是 deque 的首位之外的任何位置添加元素,都需要移动元素。而且,向一个 vector 或 string 添加元素可能引起整个对象存储空间的重新分配
使用 push_back
使用 push_front