- 作者: 雪山肥鱼
- 时间:20211210 21:01
- 目的: 复习 仿函数与 lambda
仿函数
其实就是重载 ( )
示例代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Compare
{
public:
bool operator() (int a, int b) {
return a > b;
}
};
int main() {
vector<int> vi = {1,3,5,6,7,9,2,4,5,6,8,10};
//可以把对象当函数用
sort(vi.begin(), vi.end(), Compare());
for(auto & i:vi) {
cout << i <<endl;
}
return 0;
}
相当于把对象当作函数来用。
Compare C;
//sort 的 元素会往operator里塞
C.operator() (int a, int b);
为什么需要仿函数
可以携带更多的状态
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Compare
{
public:
Compare(bool f = true):flag(f) {}
bool operator() (int a, int b) {
if(flag == true)
return a > b;
else
return a < b;
}
protected:
bool flag;
};
int main() {
vector<int> vi = {1,3,5,6,7,9,2,4,5,6,8,10};
sort(vi.begin(), vi.end(), Compare(false));
for(auto & i:vi) {
cout << i <<endl;
}
return 0;
}
核心相当于:
//Compare(false) 可以化身为:
Compare C(false);
C.operator()(int a, intb);
非常明显: 可以携带更多的状态.
Lambda 表达式
结构如下:
[capture lists](parameterlist) mutable -> return type {function body}
- 最简单的lambda 表达式
int main(int argc, char *argv[])
{
//让 auto 自己去推导
auto foo = []{return 1+2;};
cout<<foo()<<endl;
cout<<[]{return 1+2;}()<<endl;
return 0;
}
- 第二小的lambda
可带参数,其实 lambda 中的 return type 可以免掉,一般会自动推导
int main(int argc, char **argv)
{
auto foo = [](int x, int y){return x+y;};
//可带默认参数S
auto foo1 = [](int x = 10, int y = 20){return x+y;};
//返回值,一般不会写,自动推导就行j了
auto foo2 = [](int x = 10, int y= 30) ->int {return x + y;};
cout<<foo(1,2)<<endl;
cout<<foo1()<<endl;
cout<<foo2(40, 50)<<endl;
return 0;
}
[ ] 闭包 与 mutable
[capture list] 闭包的含义 就是与外界无法构成联系
int main(int argc, char **argv) {
int x = 100, y = 200;
auto f = [ ]() {
x = 50;
y= 100;
};
}
上述代码会报错,报 无法抓取 x 与 y, 说明 [ ] 对 x 和 y 都没抓到。
int main(int argc, char**argv) {
int x = 100, y= 200;
//加上& 是可以的,说明 闭包里面的东西可以勾到外面的了
//引用
auto f = [&]() {
x = 50;
y = 100;
};
f();
cout<<x<<":"<<y<<endl;
}
以引用的方式 抓取了 x, y 并可以在lambda 中修改x, y 的值
- mutable
//= 复制,产生复本
auto g= [=]{
x = 50;
y = 50;
};
首先 以 [=] 的意义是 全部抓取变量,并以复制的方式传进来,但只能读,但不能写
/*里边变了,外面没j变*/
//= 复制,产生复本
auto g= [=]()mutable{
x = 50;
y = 50;
};
int x = 100;
int *p = &x;
auto func = [p]() {
*p = *p +1; //不i会报错
}
x ,y 以副本方式传进来,可以修改,但并不影响 外界 x, y 的值。
=mutable 杀伤力太大
/*需求:=杀伤力太大,勾连所有变量,我只想要x*/
//x 复制,&x x引用,修改了x的值, y,是 复本传递
auto h = [&x,y]()mutable{
int sum = 0;
sum += x;
x +=100;
};

- 简单应用
遍历 vector
int main(int argc, char **argv) {
vector<int> vi = {1,2,3,4,5,6};
for_each(vi.begin(), vi.end(), [](int &i) {
cout<<i<<endl;
});
return 0;
}
网友评论