本文内容为《C++ Primer(第五版)》相关章节整理而得。
一、顺序容器类型※
| vector | 可变大小数组 |
| deque | 双端队列 |
| list | 双向链表 |
| forward_list | 单向链表(C语言中最传统的那种链表封装过来的) |
| array | 固定大小数组,不能添加或删除元素。 |
| string | 与vector相似,专门用于保存字符。(就是常用的字符串类。) |
array#include <iostream> #include <array> int main() { std::array<int, 3> arr = { 1, 2, 3 }; std::cout << arr[0] << std::endl; return 0; }- 容器可以套容器,例如:
std::vector<std::vector<int>> v;,但是在较旧的编译器中,可能需要在两个>之间输入空格。 当容器套一个没有默认构造函数的类型时,需要传初始值,格式如下:
std::vector<noDefault> v(10, init); // 正确 std::vector<noDefault> v1(10); // 错误,缺少初始值eg
#include <iostream> #include <vector> class A { public: A(int x, int y) {}; ~A() {}; private: }; int main() { std::vector<A> v(10, A(1, 2)); // 这是正确的 return 0; }
二、关系运算符※
- 每个容器类型都支持相等运算符(==和!=)。
- 除了无序关联容器外所有容器都支持关系运算符(>、>=、<、<=)。
比较两个容器实际上是逐个元素比较的(注意,顺序会影响比较结果),例如:
std::vector<int> v = { 1, 2, 3 }; std::vector<int> v1 = { 1, 3, 2 }; bool b = v == v1; /// 结果为false,因为v[1] != v1[1],虽然所有元素都相同,但是顺序不同。大小比较也是如此。
三、顺序容器的操作※
操作 | 作用 | 用法示例 | 适用范围 | 备注 |
| swap | 交换两个同类型容器的元素 | swap(c1, c2)或者c1.swap(c2) | ||
| assign | 从不同但相容的类型赋值或者从容器的子序列赋值 | | 除array外 | |
| push_back | 向容器末尾追加元素 | 除array和forward_list之外 | 放入容器的对象是原对象的拷贝,有额外开销 | |
| push_from | 向容器头部追加元素 | list、forward_list、deque | 同push_back | |
| insert | 在容器任意位置插入新元素 | | 1、放入的元素在迭代器所指定位置之前。 2、将元素插入到vector、string、deque的任意位置也是合法的,但是这个操作可能会很耗时。 3、该操作会返回指向第一个新插入元素的迭代器。如果未加入任何元素,则返回第一个参数对应的迭代器。 | |
| emplace/emplace_from/emplace_back | 在任意位置/头部/末尾插入新元素 | | 1、与insert/push_front/push_back用法类似,但是它是 构造 元素,而不是拷贝元素,因此性能更好。 2、传给emplace的参数必须与元素类型的构造函数相匹配。 | |
| front/back | 返回首元素/尾元素的引用。 | | 作用与调用begin/end并解引用相同。 | |
| at | 访问指定下标的元素 | 会增加对边界溢出的检查,代价是会额外消耗性能。 | ||
| erase | 删除元素 | forward_list比较特殊,叫erase_after,不叫erase | ||
| pop_back | 不支持forward_list | |||
| pop_front | 不支持vector和string |
容器操作使用示例※
使用下面代码定义的ia,将ia拷贝到一个vector和一个1ist中。使用单迭代器版本的erase从list中删除奇数元素,从vector中删除偶数元素。
int ia[]={ 0,1,1,2,3,5,8,13,21,55,89 };
(1)拷贝元素※
方法一
std::vector<int> v(ia, ia + sizeof(ia) / sizeof(ia[0]));方法二
v.assign(ia, ia + sizeof(ia) / sizeof(ia[0]));方法三
#include <iterator> std::vector<int> v(std::begin(ia), std::end(ia));
(2)删除元素※
方法一:根据题目要求的做法
for (std::vector<int>::iterator it = v.begin(); it != v.end();) { if (*it % 2 == 0) { it = v.erase(it); } else { ++it; } }方法二:比方法一效率更高,实际项目中更推荐使用这种方法
#include <algorithm> // C++11之前 bool isEven(int n) { return n % 2 == 0; } v.erase(std::remove_if(v.begin(), v.end(), isEven), v.end()); // C++11之后(Lambda表达式) v.erase(std::remove_if(v.begin(), v.end(), [](int n) {return n % 2 == 0; }), v.end());