| 容器 | 容器特点 |
---|
vector | 可变大小的数组。支持快速随机访问,在尾部之外的位置插入或删除元素可能会很慢。 |
deque | 双端队列。支持快速随机访问。在头尾位置插入/删除速度很快 |
list | 双向链表。只支持双向顺序访问。在list中任何位置进行插入/删除操作速度都很快。 |
forward_list | 单向链表。只支持单向顺序访问。在链表任何位置进行插入/删除操作速度都很快。 |
array | 固定大小数组。支持快速随机访问。不能添加或删除元素 |
string | 与vector相似的容器,但专门用于保存字符。随机访问快。在尾部插入/删除速度快。 |
容器类的通用操作如下:
| 容器操作 | |
---|
类型别名 | |
iterator | 可读可写容器类型的迭代器类型 |
const_iterator | 可以读取元素,但不能够修改元素的迭代器类型 |
size_type | 无符号整数类型,足够保存此种容器类型最大可能容器的大小 |
difference_type | 带符号整数类型,足够保存两个迭代器之间的距离 |
reference | 元素的左值类型;与value_type&含义相同 |
const_reference* | 元素的const左值类型(const value_type&) |
构造函数 | |
C c; | 默认构造函数,构造空容器(array使用:array< int, 10 >) |
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) | 与a.swap(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_iterator |
反向容器的额外成员(不支持forward_list) | |
reverse_iterator | 按逆序寻址元素的迭代器 |
const_reverse_iter | 不能修改元素的逆向迭代器 |
c.rbegin(), c.rend() | 返回指向c的尾元素和首元素之前位置的迭代器 |
c.crbegin(), c.crend() | 返回const_reverse_iterator |
容器的定义与初始化:
| 初始化方式 | 详解 |
---|
C c; | 默认构造函数。如果C是一个array,则c中元素按默认方式初始化;否则c为空 |
C c1(c2) | c1初始化为c2的拷贝。c1和c2必须是相同类型(容器类型相同,且保存的是相同类型的元素;对于array来说,还必须具有相同大小) |
C c1=c2 | 同上 |
C c{a,b,c…} | c初始化为初始化列表中元素的拷贝。列表中元素的类型必须与C元素类型相容。对于array类型,列表中元素数目必须等于或者小于array的大小,任何遗漏的元素都是个进行值初始化 |
C c={a,b,c…} | 同上 |
C c(b,e) | c初始化为迭代器b和e指定范围中的元素的拷贝。范围中元素的类型必须与C的元素类型相容(array不适用) |
只有顺序容器(不包括array)的构造函数才能接受大小参数 | |
C seq(n) | seq包含n个元素,这些元素进行了值初始化;此构造函数是explicit的(string不适用) |
C seq(n,t) | seq包含n个初始化为值t的元素 |
array具有固定大小,与其他容器不同
array的大小也是它的一部分,而且它不支持普通构造函数。与内置数组类型不同的是,array可以拷贝和赋值操作。
容器赋值运算
| 操作 | 详解 |
---|
c1=c2 | 将c1中的元素替换为c2,必须相同类型 |
c={a,b,c…} | 将c1中元素替换为初始化列表中元素的拷贝(array不适用) |
swap(c1,c2) | 交换两元素,相同类型,swap通常比c2向c1拷贝快得多 |
c1.swap(c2) | 同上 |
assign操作不适用于关联容器和array | |
seq.assign(b,e) | 将seq中的元素替换为b和e所表示范围内的元素。不能指向seq |
seq.assign(il) | 将seq中的元素替换为初始化列表il中的元素 |
seq.assgin(n,t) | 将seq中的元素替换为n个值为t的元素 |
PS:赋值相关运算会导致指向左边容器内部的迭代器,引用和指针失效。而swap操作将容易内容交换不会导致以上内容失效(容器类型为array和string的情况除外)。最好使用非成员版本的swap(好习惯)
向顺序容器添加元素的操作:
| 这些会改变array的大小 | array不支持这些操作 |
---|
forward_list有自己转悠版本的in 4000 sert和emplace | |
forward_list不支持push_front和emplace_front | |
vector和string不支持push_front和emplace_front | |
c.push_back(t)、c.emplace_back(args) | 在c的尾部创建一个值为t或由args创建的元素,返回void |
c.push_front(t)、c.emplace_front(args) | 在c的头部创建一个值为t或由args创建的元素,返回void |
c.insert(p,t)、c.emplace(p,args) | 在迭代器p指向的元素之前创建一个值为t或由args创建的元素。返回指向新添加的元素的迭代器 |
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是一个花括号包围的元素值列表。将这些给定值插入到迭代器p指向的元素之前。返回指向新添加的第一个元素的迭代器;若列表为空,则返回p |
PS:向一个vector、string、deque插入元素会使所有指向容器的迭代器、引用和指针失效。PPS:在我们使用这些操作时,必须使用不同的策略来分配元素空间,在一个vector、string的尾部之外的任何位置,或是一个deque的首尾之外的任何位置添加元素,都需要移动元素。而且向一个vector或string添加元素可能引起整个对象存储空间的重新分配。重新分配一个对象的存储空间需要分配新的内存,并将元素从旧的空间移动到新的空间中。删除元素
| 操作 | 详解 |
---|
这些操作会改变容器的大小,所以不适用与array | |
forward_list有特殊的版本erase | |
forward_list不支持pop_back;vector和string不支持pop_front | |
c.pop_back() | 删除c中尾元素。若c为空,则函数行为未定义。返回void |
c.pop_front() | 删除c中首元素。若c为空,未定义,返回void |
c.erase(p) | 删除迭代器p所指定的元素,返回一个指向被删元素之后元素的迭代器,若p指向尾元素,则返回尾后迭代器。若p是尾后迭代器,则行为未定义 |
c.erase(b,e) | 删除b,e所制定范围内的元素。返回最后一个被删元素的之后元的的迭代器,若e本身就是尾后迭代器,则函数也返回尾后迭代器。 |
c.clear() | 删除c中的所有元素。返回void |
PS:删除deque中除了首尾位置之外的任何元素都会使所有迭代器、引用和指针失效。指向vector或string中删除点之后位置的迭代器、引用和指针都会失效。 | 在forward_list中插入或删除元素的操作 | |
---|
lst.before_begin() | 返回一个链表首元素之前不存在的元素的迭代器。不能解引用 |
lst.cbefore_begin() | 返回一个const——iterator |
lst.insert_after(p,t)、lst.insert_after(p,n,t)、lst.insert_after(p,b,e)、lst.insert_after(p,il) | 在迭代器p之后的位置插入t,n是数量,b和e是表示范围的一对迭代器(b和e不能指向lst内),il是一个花括号列表。范围一个指向最后一个插入元素的迭代器。如果范围为空,则返回p。若p为尾后迭代器,则函数行为未定义 |
emplace_after(p,args) | 使用args在p制定位置之后创建一个元素 |
lst.erase_after(p)、lst.erase_after(p,e) | 删除p指向的位置之后的元素,或删除从b之后直到e之间的元素。返回一个指向被删除元素之后元素的迭代器,若不存在这样的元素,则返回尾后迭代器。如果p指向lst的尾元素或者是一个尾后迭代器,则函数行为未定义 |
改变容器大小:
| resize不适用于array | |
---|
c.resize(n) | 调整c为大小为n的元素,若n大于原来的size,则添加新元素并进行值初始化。若小于原来size,多出的元素则被舍弃 |
c.resize(n,t) | 调整c的大小为n个元素。任何新添加的元素都初始化为t |
PS:如果resize缩小容器,则指向被删除元的的迭代器、引用、指针都会失效;对vector、string、deque进行resize可能导致迭代器、指针和引用失效。管理容量的成员函数:
| 容器大小管理操作 | |
---|
shrink_to_fit只适用于vector、string、deque | |
capacity和reserve只适用于vector和string | |
c.shrink_to_fit() | 请将capacity()减少为和size()相同大小(仅为一个请求,标准库不一定会归还内存) |
c.capacity() | 不重新分配内存空间的话,c可以保存多少元素 |
c.reserve(n) | 分配至少能容纳n个元素的内存空间 |
PS:reserve并不改变容器中元素的数量,它仅影响vector预先分配多大的内存空间string操作:
| 构造string的其他方法 | n、len2和pos2都是无符号值 |
---|
string s(cp,n) | s是cp指向的数组前n个字符的拷贝,此数组至少应该包含n个字符 |
string s(s2,pos2) | s是string s2从下标pos2开始的字符的拷贝 |
string s(s2,pos2,len2) | s是string s2从下标pos2开始len2个字符的拷贝。不管len2的值是多少,构造函数至多拷贝s2.size()-pos2个字符 |
substr(pos,n) | 返回一个string,包含s中从pos开始的n个字符的拷贝。pos的默认值为0。n的默认是为s.size()-pos,即拷贝从pos开始的所有字符 |
修改string的操作 | |
s.insert(pos,args) | 在pos之前插入args指定的字符。pos可以是一个下标或一个迭代器。接受下标的版本返回一个指向s的引用;接受迭代器的版本返回指向第一个插入字符的迭代器 |
s.erase(pos,len) | 删除从位置pos开始的len个字符。如果len被省略,则删至末尾。返回一个指向s的引用 |
s.assign(args) | 将s中的字符替换为args指定的字符。返回一个指向s的引用 |
s.append(args) | 将args追加到s。返回一个指向s的引用 |
s.replace(range,args) | 删除s中范围range内的字符,替换为args指定字符。range或者是一个下标和一个长度,或者是一对指向s的迭代器。返回一个指向s的引用 |
args可以是下列形式之一append和assign可以使用所有形式。 | str不能与s相同,迭代器b和e不能指向s |
str | 字符串str |
str,pos,len | str中从pos开始最多len个字 |
cp,len | 从cp指向的字符数组的前len个字符 |
cp | cp指向的以空字符结尾的字符数组 |
n,c | n个字符c |
b,e | 迭代器b和e指定的范围内的字符 |
初始化列表 | 花括号包围的,以逗号分隔的字符列表 |
replace和insert所允许的args形式依赖于range和pos是如何指定的 | |