概述
头文件:algorithm、numeric
泛型算法永远不会执行容器的操作,运行于迭代器之上,执行迭代器的操作。
10.2 初始泛型算法
10.2.1 只读算法
find
find(vec.begin(),vec.end(),val);
accumulate(求和)
accumulate(vec.cbegin(),vec.end(),0);//求和,和的初值设置为0
10.2.2写容器的算法
算法不会检查写操作
fill
fill(vec.begin(),vec.end(),0);
拷贝算法
copy(vec.begin(),vec.end(),vec2);//同样大小
replace(vec.begin(),vec.end(),0,44);//将所有0替换为44
10.2.3 重排容器元素的算法
sort
排序算法
unique
去除排好序后的重复元素
10.3 定制操作
sort算法使用默认<
10.3.1 向算法传递函数
sort可以接受第三个参数——谓词(默认<)
稳定的排序算法 stable_sort
相同元素之间的相对顺序不会改变
10.3.2 lambda表达式
谓词最多只有二元,当我们需要算法进行操作的参数更多时,可以使用lambda表达式
stable_sort(words.begin(),words.end(),[](const string &a,const string &b)
{return a.size()<b.size();});
使用捕获列表
一个lambda只有在其捕获列表中捕获一个它所在函数中的局部变量,才能在函数体中使用该变量。
auto wc=find_if(strs.begin(),strs.end(),[sz](const string &a){return a.size()>=sz;});
stable_sort() 稳定的排序算法
find_if() 找到第一个满足条件的迭代器
for_each() 遍历每一个迭代器,接受一个可调用的对象,将每一个元素调用此对象。
10.3.3 lambda的捕获和返回
值捕获
引用捕获
指定lambda返回类型
10.3.4 参数绑定
由于像find_if这种类型中需要调用一个lambda来完成比较,但是如果调用一个普通函数的话就不可以。
bool check_size(const string &s,string::size_type sz)
{
return s.size()>=sz;
}
标准库bind函数(头文件functional)
auto check6=bind(check_size,_1,6);
string s="hello";
bool b1=check6(s);
通过bind我们可以将以前基于lambda的find_if调用替换为如下使用check_size的版本
auto wc=find_if(words.begin(),words.end(),[sz](const string &a))
auto wc=find_if(words.begin(),words.end(),bind(check_size,_1,sz);//等价
使用placeholder名字
占位符需要using声明:
using namespace placeholders;
bind参数
auto g=bind(f,a,b,_2,c,_1);
g(_1,_2);//映射
绑定引用参数
比如ostream对象必须使用引用参数,所以不能直接用bind绑定。可以用标准库中的ref函数
10.4 再探迭代器
- 插入迭代器:被绑定到一个容器上,可以用来向容器插入元素
- 流迭代器:被绑定到输入或者输出流上,可以遍历所关联地io流
- 反向迭代器:向后移动,除了forward_list之外的标准库容器都有反向迭代器
- 移动迭代器:用来移动元素
10.4.1插入迭代器p358
front_inserter:总是插入到当前元素之前
inserter:插入到当前元素之后
10.4.2 iostream迭代器
10.4.3反向迭代器
10.5.3 算法命名规范
_if版本的算法:接收一个谓词代替元素值