顺序容器
string是类似vector的,但更适用于字符。
deque,双端队列,但不是用list实现的。
queue,单端队列,使用deque或者list实现。在默认情况下使用deque实现。
array不是内置数组,是一种数据结构,优于内置数组。
有的时候容器会需要更多的参数。如对于一个没有默认构造函数的类型定义一个定长度的vector时,需要提供初始化器。
c.emplace(inits)用初始化器添加一个元素。
reference是引用
反向迭代器++是到上一个元素。
容器的拷贝有两种
- 拷贝整个容器,必须保证元素类型相同
- 用两个迭代器指定拷贝范围,不要求元素类型相同,只需能够转换即可
当使用列表初始化时不但指定了值也指定了大小。
只有顺序容器支持初始化大小。
array
在指定类型外还要指定大小。
允许拷贝。
但是array类型必须类型与大小相同。
assign不止能将相同的容器进行拷贝,不同的容器也可以通过这种方式进行拷贝。
不能将自己assign给自己,因为旧迭代器会失效。
swap若用在array之外,其交换并不交换具体元素,而是交换数据结构。因此很快且迭代器不会失效。
max_size返回的是能容纳的最大元素数,应该是跟内存大小有关?。
关联容器可以判断等于,两个顺序容器还可以进行比较。
若是前缀,这短的更小。
若不是,则根据第一个不同的值的大小。
容器的等于是依靠类型的等于,容器的其他比较是依靠类型的小于。
可以通过这些函数的返回值来反复插入元素。
emplace通过传入的args并以之为参数调用构造函数并将构造出的元素插入。会在内存空间中直接创建元素。而push会先创建一个临时的,然后再插入。
front和back必须先保证容器非空。
由于front和back返回的是引用,虽然也有常量引用的重载。
下标运算符并不会判断是否越界,但可以通过.at(index)来加上判断。若是越界,则会抛出异常。
删除元素必须保证元素存在在容器中。
forward_list
单向链表,比list运行效率上更优并且空间上更优。
由于是单向的,但是更改当前元素会影响到前面一个元素,因此所有的操作都是更改当前元素的后面一个元素。并且提供首前指针接口。
对于vector和string,插入或删除若没有重新分配,则其前的所有将仍有效,而后都无效。
对于deque,只有在插入或删除头尾时不会失效,而其他情况所有都会失效。
必须保证迭代器有效。
通过insert和erase的返回值来更新迭代器。insert返回插入的最后一个,erase返回删除的后面一个。
end()返回的迭代器常常会在容器元素改变时失效,因此使用时应该直接调用,不要保存。
begin()倒是问题不是很大,但还是要注意一下。
Vector
提供capacity()与reserve()接口。capacity返回当前申请的总空间中能存储几个数据。而reserve(int)使vector先进行分配一定量的空间若是当前的capacity小于请求量时。
当申请新的空间时,一般是翻倍,但是这也会因实现不同而不同。
另外shrink_to_fit()可以建议vector去掉多余的空间,但不一定会执行。
String
有较多函数,主要有几个方面。
容器适配器
容器适配器就是使用别的容器来实现的效果一致的容器。
stack,queue,priority_queue都是容器适配器。是通过其他容器实现的。
虽然使用其他的容器实现,但是不能访问实现它的容器的底层接口,只能调用其特有的接口。因此stack与priority_queue有top()这种其他容器所没有的接口。
可以将其他的容器元素全部拷贝来初始化。
由于一个容器适配器可以用多种容器实现,因此,在定义一个容器适配器时可以指定实现的底层容器。
stack,可以使用所有除forward_list和array的容器。
queue,可以使用list或deque。
priority_queue,可以使用vector或deque。
默认都是使用deque实现的。