核心简记
- 泛型算法作用于各种容器,大多数定义在algorithm中
- 指针可以当做迭代器传入泛型算法中。
- 泛型算法本身不执行容器的操作,只运行于迭代器上,因此不会改变底层容器的大小。除非改变是迭代器的效果
- copy版本的算法将结果放入新序列
- using namespace name; 将name下的名字都引入
算法查表可以参考:
https://blog.csdn.net/strint/article/details/45308001
定制操作
算法有额外的参数可以指定操作代替元素<=等操作
可调用对象>谓词(可调用的表达式、返回为条件值) 函数的指针可以做谓词。
传函数指针谓词时参数被限定了,不能加控制参数。使用lambda可以传入其它参数。
lambda:适用于一俩个地方使用的简单操作
忽略参数列表与()为空参数
忽略返回类型根据函数体推断,但体仅一个return。 返回类型必须尾置
lambda只能使用明确指明的外层函数局部变量。指明通过捕捉列表。可以直接使用所在函数外的名字与局部静态变量
lambda实际上是定义了一个新类型与其对象。该对象含捕获变量的数据成员,创建对象时初始化。
捕获的变量为lambda创建时拷贝,若要引用则[&a]即可。因为函数可以返回lambda对象因此作用域与生存期当心。
默认下不会改变捕获的值,想要在lambda中改变捕获的值要在参数列表后加mutable
函数也可以使用包装来达到多传参数的效果
生成一个新的函数适应参数列表。默认为拷贝,因为是传参而不是定义,因此引用也会化为拷贝,非占位符的参想引用传入要用库函数ref()返回可拷贝的引用对象。
迭代器
头文件iterator定义了额外的集中迭代器。
插入迭代器:
是对容器的包装,使用插入迭代器可以对容器插入元素,有三种插入迭代器:尾、头、指定位置。
流迭代器:
输入与输出流的迭代器。可以使流使用泛型算法。
输入流的操作多些:使用*返回读取的值,使用++读取下一个。
输出使用=输出
反向迭代器:
反向操作,容器必须同时支持++与–
调用反向迭代器的.base()方法可以返回正常迭代器,不过位置不同,因为[)要向后挪一个
移动迭代器:移动迭代器的解引用返回右值引用:
对其的解引用将使用右值引用。普通的是返回左值引用
泛型算法结构
算法的基本特性是要求迭代器提供哪些操作,可分为5个迭代器类别:其功能逐层增加
输入迭代器:只读,不写,单遍递增。如流输入迭代器
输出迭代器:只写,不读,单遍递增。如流输出迭代器
前向迭代器:读写,多遍递增。如forward_list的迭代器
双向迭代器:读写,多遍,可增可减。除了fl的库迭代器
随机访问迭代器:读写,多遍,随机读写。array、deque、string、vector都是
算法的参数模式:
- 一些有接受谓词的重载实现,如unique
- 后缀_if的版本可以接受谓词代替原元素值,如find
- 写回另一个指定输出目的的拷贝版本,后缀_copy
list与fl不用通用版本,其以成员函数形式实现了自己的版本,因为不拷贝效率更高。如:merge、remove、reverse、sort、unique。splice用于俩个之间移动元素。链表特有的会改变容器。
反汇编
|
|
x86-64
FS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值;
GS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值。
|
|
|
|
ARM-64
|
|
|
|
可见lambda在c++中实现的本质就是一个类与对象,自定义的类代码位于code,捕获的数据作为对象成员,创建lambda时创建对象,并用指定的局部变量初始化对象成员,之后使用该对象重载的调用运算符使用该部分数据。会传入this