1、补充:vector<T> v4(n) 开了一个包含n个0的vector v4
一、迭代器
1、回顾我们之前的迭代方式:
迭代器看起来像一个指针 注意.end()是最后一个元素的下一个位置
.end()又叫尾后迭代器 the off-the-end iterator
尾后迭代器是不能递增或者解引用的,这是未定义的行为
基于范围的for语句的原理 range-for:
前置加加减减的好处:不会发生额外的拷贝,对于迭代器来说,前置加加减减更好
const_iterator
迭代器的其他操作:
特别注意迭代器的相减 end()-begin()就相当于size()
迭代器相减的返回结果类型实际上是个带符号的整数类型
迭代器的大小比较只能是对同一个容器的迭代器进行比较,如某个vector的指向第一个索引的iterator<指向这个vector的第三个索引的iterator
否则就是undefined behaviour
二、顺序容器
STL中的容器分为顺序容器和关联容器
复习一下六种初始化方式:
下面引入了反向迭代器
反向迭代器的加加实际上是倒着走
插入/删除元素:
理解insert and erase:
emplace的意义:转发
上面vp.emplace_back(3.5,6)做到了直接把3.5,6这个参数传给Point2d的构造函数,并且直接往vector里添加
如果我们用的是vp.push_back(Point2d(3.5,6))那么会额外发生一个拷贝,就是Point2d返回的值要拷贝成push_back所需要的参数,这实际上要求vector里面数据的类型必须是可拷贝的
所以说,emplace没有这样的限制
例如这次作业中,不要写出那些依赖于默认构造和拷贝构造的代码,因为vector/list中的数据可能不支持这些!
例如这次作业中写链表的相等和小于运算符,不要出现依赖于其他运算符的代码!
这两个可能会很方便(填坑)
Iterator Categories 迭代器分类
输入/输出迭代器,前向迭代器,双向迭代器,随机访问迭代器
容器适配器 container adapters
栈,队列,优先队列 CS101不允许使用STL 但是似乎可以自己造……(gknb!)
上面的代码是宽度优先搜索的,展示了队列的使用
vector<bool> 画蛇添足
boost库是在了解了标准库之后最应该了解的库
三、泛型算法
作业里面实际上可以直接用标准库里面这些算法
相等直接用std::equal(), 小于直接用std::lexicographical_compare()
上面代码叫做离散化:先排序,然后去重 注意unique()会把重复的元素放在vector的末尾,返回的迭代器指向的是不重复元素的下一个位置
传给unique的vector必须是从小到大排好序的
要查算法,就去看书!
注意:在标准库算法中设计排序的,默认情况下都是从小到大
下面我们举一个例子,Point2d中的点按横坐标排序
-----讲解的实际上是自己规定的排序规则
对于static函数,记住两点:
它不是成员函数;它在类作用域内
这也就解释了,为什么static函数必须用类名::来调用
而且static函数中没有this指针,因为它不是成员函数
另外一个例子:找到第一个小于10(或者小于k) 的元素 用到了find_if()函数
上面实际上是个调用运算符的重载
Less_than(k)通过调用构造函数返回了一个Less_than类型的对象
上面在给std::sort传参的时候之所以用了Cmp_x{}这个花括号,就是为了告诉你,这是个默认构造罢了!
Lambda表达式:是一个匿名函数
里面的中括号叫做捕获列表