算法永远不会改变底层容器的大小。可能改变元素的值,也可能移动元素,不会直接添加或删除元素。
算法的定制操作:
谓词:一种可调用的表达式,返回结果是一个能用作条件的值。
一元谓词:只接受单一参数。
二元谓词:接受两个参数。
可调用对象:
1. 函数
2. 函数指针
typedef void(*PFUNC)(void); 指针类型 PFUNC
void(*pFunc)(void); 函数指针
3. 重载了函数调用运算符的类 () 符号重载
4. lambda表达式
[capture list](parameter list) -> return type {function body}
1. 捕获列表只用于局部非static变量,lambda 可以直接使用局部 static 变量和它所在函数之外声明的名字。
2. 值捕获:被捕获的变量的值在 lambda 创建时拷贝,而不是调用时。
3. 引用捕获:确保 lambda 执行时被引用对象存在。
4. 隐式捕获:& 引用方式,= 值捕获方式。混合时,第一个需为隐式捕获,显示捕获的变量需与隐式不同,如 [=,const int & sz].
5. mutable 关键字:可改变被捕获变量的值。
6. 如果一个 lambda 包含 return 之外的任何语句,编译器就无法推断出返回类型,则此 lambda 返回 void,此时需要使用尾置返回类型。
7. 适用于一两处使用的简单操作。
5. 参数绑定bind函数
auto newCallable = bind(callable, arg_list);
1. arg_list 中可能包含如 _n (n为整数)的名字,这些参数是占位符,为 newCallable 的参数。如 auto newC = bind(oldC, 8, _2, _1); 表示将 newC 的第 2 个参数传给 oldC 的第 2 个参数, 第 1 个参数传给 oldC 的第 3 个参数,且 newC 只有两个参数。达到参数个数或顺序调整的目的。
2. 名字 _n 都定义在 std 的 plaseholder 的命名空间中,所以需要using namespace std::placeholders
。需要包含 #include <functional>
。
3. bind 拷贝非占位符的参数到 newC 中。可以使用标准库函数 ref 传递一个引用对象。如 bind(print, ref(os), _1, ' ');
其他迭代器:
插入迭代器(insert iterator):通过插入迭代器赋值,会调用相应容器(容器支持该操作时)操作来插入一个元素。
back_iterater :使用 push_back 容器操作。
front_iterater:使用push_front 容器操作。
inserter:使用 insert 容器操作。
流迭代器(stream iterator)
反向迭代器(reverse iterator)
移动迭代器(move iterator)
泛型算法结构
1. 5类迭代器
输入迭代器
输出迭代器
前向迭代器
双向迭代器
随机访问迭代器
2. 算法形参模式
alg(beg, end, other args);
alg(beg, end, dest, other args);
alg(beg, end, beg2, other args);
alg(beg, end, beg2, end2, other args);
3. 算法命名规范
1. 一些算法使用重载形式传递一个谓词
2. _if 版本的算法(接受一个谓词)
3. 区别拷贝元素版本和不拷贝版本