仿函数、STL算法、lambda表达式
仿函数
重载了 operator(),像函数一样使用的 类对象,就叫仿函数。是STL算法与容器之间灵活定制操作的核心机制
本质
它是个对象,但重载了 operator(),所以可以像函数一样调用。
相对于普通函数的优势
1.可保持状态:通过构造函数传入参数
2.可内联优化
3.每个仿函数都有独特类型
头文件
<functional>
<algorithm> //STL算法头文件
举例
template<class T>
class Add {
public:
T operator()(T a, T b) {
return a + b;
}
};
int main() {
Add<int>addF;//创建类对象
//对象作为函数调用
cout << addF(100, 20) << endl;
return 0;
}
补充说明
依赖仿函数的参数个数,又分一元仿函数、二元仿函数、三元仿函数
如果仿函数返回bool,又称之为谓词,依据参数个数又分为一元谓词,二元谓词,三元谓词
仿函数是用于容器与算法之间的。
谓词
operator()返回的类型是bool
STL自带的仿函数
1.算数运算
二元仿函数,参数表有两个形参
- 负号 negate
int main() {
int n = 100;
auto f = negate<int>();//创建仿函数的类对象
const int ret =f(n);//对象作函数使用
cout << ret << endl;
auto f2 = plus<int>();//加运算仿函数
cout << f2(1, n) << endl;
cout << f2(50, n) << endl;
auto f3 = multiplies<int>();//乘法运算仿函数
cout << f3(20, 40) << endl;
auto f4 = divides<int>();//除法仿函数
auto f5 = modulus<int>();//取余
auto f6 = minus<int>();//减法
return 0;
}
2.关系运算
int main() {
auto f1 = less<>();//小于
auto f2 = less_equal<>();//小于等于、
auto f3 = greater<>();//大于
auto f4 = greater_equal<>();//大于等于
auto f5 = equal_to<>();//==
auto f6 = not_equal_to<>();//!=
cout << f1(11, 25) << endl;//1
cout << f2(11, 11) << endl;//1
cout << f3(21, 3) << endl;//1
cout << f4(21,18 ) << endl;//1
}
3.逻辑运算符仿函数
int main() {
auto f1 = logical_and<>();//&&逻辑与
auto f2 = logical_or<>();//||逻辑或
auto f3 = logical_not<>();//!逻辑非
}
4.位运算仿函数

STL算法
STL算法,基本上都是操作容器的迭代器,外加数据处理的仿函数
头文件
#include<algorithm>
for_each
遍历一个迭代器区间 [first, last),对区间内的每一个元素,执行一次你指定的函数 / 操作。
它不修改容器结构(不增删元素),只负责遍历 + 执行回调。
#include<vector>
#include<list>
#include<map>
#include<set>
template<class T>
void show1(T item) {
cout << item << " ";
}
int main() {
vector<int>ns{ 5,2,1,3,4,9,8,7,4,6 };
for_each(ns.begin(), ns.end(), show1<int>);
cout << endl;
list<string>names{ "disen","lucy","Yang Sir","Zhang Sir" };
for_each(names.begin(), names.end(), show1<string>);
cout << endl;
return 0;
}
//任务:自定义for_each算法
template <class Itr,class F>
void forEach(Itr begin, Itr end, F callback) {
while (begin != end) {
callback(*begin);
begin++;
}
}
all_of any_of
all_of:逻辑:一处不满足,直接返回 false
any_of:逻辑:一处满足,直接返回 true
bool funcl(int item) {
return item > 5;
}
int main() {
vector<int>ns{ 5,2,1,3,4,9,8,7,4,6 };
//al1_of 容器中每一个元素都满足条件 func1返回的结果都为true
bool ret1=all_of(ns.begin(), ns.end(), funcl);
cout << ret1 << endl;//0
//any of 容器中任一个元素满足条件,则返回true
bool ret2 = any_of(ns.begin(), ns.end(), funcl);
cout << ret1 << endl;//0
return 0;
}
search
在一个序列中查找另一个子序列第一次出现的位置
count
统计区间内等于目标值的元素个数
auto ret3 = count(ns.begin(), ns.end(), 4);
cout << "4元素的个数:" << ret3 << endl;
list<int>ns2(ns.begin(), ns.end());
ret3 = count(ns.begin(), ns.end(), 9);
cout << "9元素的个数:" << ret3 << endl;
count_if
//统计大于5 的个数
ret3 = count_if(ns2.begin(), ns2.end(), funcl);
cout << "大于5的个数:" << ret3 << endl;
复制与交换
copy
将源区间 [first,last) 元素拷贝到目标迭代器起始位置
copy(v.begin(), v.begin() + 3, v2.begin());
cout << "v2 size:" << v2.size() << endl;
for_each(v2.begin(), v2.end(), show);
cout << endl;
copy_if
筛选满足条件的元素,拷贝到目标区间
swap
交换
swap_ranges
交换两个等长区间元素
transform
遍历容器,对每个元素做转换 / 处理,把结果放到目标容器
- for_each:只执行操作,不赋值、不生成新容器
- transform:执行转换,把结果写入新容器
replace
遍历区间,把等于 old_val 的元素,全部替换成 new_val 等值替换
replace_if 条件替换
满足条件就替换
STL 移除 / 填充类算法
fill
给容器指定范围的所有元素,统一填充同一个固定值。
generate
给容器指定范围的元素,通过调用自定义函数动态生成,支持随机数、序列等可变内容。
移除类算法:remove /remove_if/unique
把需要保留的元素向前移动,把要删除的元素移到容器末尾,最终返回第一个待删除元素的迭代器。
remove
移除容器中等于指定值的所有元素。
将删除的元素移动到尾部,并返回删除元素的开始位置。
删除操作删除元素的内容,空间还在,只是排列到后面去了,空间内容是尾部数据的替换
remove_if
移除容器中满足自定义条件的所有元素,灵活性远高于remove。
unique
移除容器中相邻的重复元素,只保留第一个。
复制 + 移除类算法:remove_copy /remove_copy_if
和remove/remove_if逻辑一致,但不会修改原容器,而是把保留的元素,复制到一个新的目标容器中。
lambda表达式
定义
生成一个匿名函数
语法
[局部变量捕获列表](参数表)->返回类型{ }
[ ] 空,函数体内不访问外部局部变量
[=] 值,函数体可以访问外部的局部变量,但是只读。如果要修改,必须声明mutable
[&] 引用,函数体内访问外部变量,以引入的方式
[a] 单变量 值,函数体内只能访问 a 局部变量
[a,b] 多变量 值,函数体内只能访问a,b局部变量
[&a] 单变量引用
[&a,&b] 多变量引用
[a,&b] a是值,b是引用
[&,a] a是值,其他的局部变量是引用方式捕获
[=,&a] a是引用,其他的局部变量是值
最简短的lambda表达式
1.[ ]{ }
2.[=]()mutable{ }
捕获列表
引入局部变量的方式
=值引入 ,创建副本,默认只读,如果要改内容时,加mutable
&引用
变量名 ,... 默认值引入
&变量名, 引用方式
变量名,&变量 组合方式
mutable
=值得方式捕获时,创建局部变量的副本,默认副本是只读的。
这个关键字可以修改副本。
int main() {
int x = 1, y = 5;
//f是lambda表达式 名称
//f 也是函数名
auto f = [=](int a)mutable->int {
//=值得方式捕获时,默认副本是只读的
x++;
y += 5;
cout << "lambda:" << x << "," << y << endl;
return (x + y) * a;
};
return 0;
}
=值捕获时,表达式内部修改变量值,不影响外部的变量
&引用,局部变量在块中是引用的方式使用,内外是同步的。
删除拷贝
remove_copy
复制非指定值到新容器
跳过v中指定元素(要删除),其他元素复制到v2。
remove_copy_if
复制不满足条件的元素到新容器
更多推荐
所有评论(0)