shellmad-10_C++新特性 lambda表达式与匿名函数

代码中会遇到这样一种情况, 写的某一个函数, 有可能只会被调用1次, 或者说不会在被其他地方复用了, 这时候专门写一个函数就不太划算, 但是不写的话, 代码逻辑就会比较混乱, 所以就有一个匿名函数的东西

举个例子
比如点击某个按钮, 会执行某个动作

那么在执行动作的时候, 对应的是某个函数的处理

而实际上动作只是针对于这个点击操作而言的, 才触发的
在其他地方都不会被使用到的, 只有在这里被使用的, 所以最好的方式是为他提供一个匿名函数
在这里插入图片描述
在这里插入图片描述

lambda表达式就是匿名函数(没有名字的函数)

一般函数写法
返回值类型 函数名字(参数类型1 参数1, 参数类型2, 参数2) {
}
然后一般函数可以定义在main函数外面

lambda写法:

	// []捕获列表 ()参数列表 ->返回值
	[](int a, int b) -> int{
		// 函数体
	}

因为是匿名函数, 所以就没有名字, 名字可以省略, 直接跟上参数列表
返回值不能写前面, 因为写前面, 相当于函数声明的写法, lambda表达式返回值一般写参数列表后面, 写在后面 [](int a, int b) int也不大对, 因此加了个->

调用的问题, 因为是匿名函数, 所以刚刚写好, 得立即调用, 其他地方很难调用

所以直接调用
(1, 2)代表传入参数, 再跟个;表示程序可以执行

	// []捕获列表 ()参数列表 ->返回值
	[](int a, int b) -> int{
		// 函数体
		return a + b;
	}(1, 2);

匿名函数会返回一个结果, 结果放哪里了呢, 前面来个变量接受

	// []捕获列表 ()参数列表 ->返回值
	int c = [](int a, int b) -> int{
		// 函数体
		return a + b;
	}(1, 2);

等价于

int Foo(int a, int b){
	return a + b;
}

int main(){
	...
	c = Foo(1, 2);
}

因为定义了一个没有名字的函数, 定义的时候可以立马调用, 而在定义完了之后, 程序的其他地方, 再也不能调用

所以为了避免这种情况, 将后面的(1, 2);去掉, 那么下面表示的是一个函数体类型, 是函数体的话, 是不是可以存储起来, 存储的类型是啥呢?
auto代表类型就可以了

	// []捕获列表 ()参数列表 ->返回值
	[](int a, int b) -> int{
		// 函数体
		return a + b;
	};

auto f去接受这个函数体


	// []捕获列表 ()参数列表 ->返回值
	auto f = [](int a, int b) -> int{
		// 函数体
		return a + b;
	};

总代码:

#include <iostream>
using namespace std;
int main(){
		// []捕获列表 ()参数列表 ->返回值
	auto f = [](int a, int b) -> int{
		// 函数题
		return a + b;
	};

	cout << f(1, 2) << endl;
	return 0;
}

lambda的作者认为: 所有的程序都可以归纳为用lambda来表达, 所有程序都可以写到一起, 变成一个函数

他也从数学上证明了这一点

尝试写一下两个lambda嵌套

两个lambda嵌套

	[](int n){
		[](int x){

		};
	};

然后 [] (int n){};内部需要返回结果 [](int x){};的结果, 所以在[](int x){};前面加了return

	[](int n){
		return [](int x){

		};
	};

然后内部[](int x){}; 需要用到外部的变量, 所以用中括号捕获外部变量n

	[](int n){
		return [n](int x){

		};
	};

最后补上内部函数体, 然后为了调用内部函数, 在末尾加上传入的实参(1);
外面也需要传实参(2);

	[](int n){
		return [n](int x){
			return n + x;
		}(1);
	}(2);

然后用变量int c接收

	int c = [](int n){
		return [n](int x){
			return n + x;
		}(1);
	}(2);

总代码:

#include <iostream>
using namespace std;
int main(){
	// 	// []捕获列表 ()参数列表 ->返回值
	// auto f = [](int a, int b) -> int{
	// 	// 函数体
	// 	return a + b;
	// };

	// cout << f(1, 2) << endl;

	int c = [](int n){
		return [n](int x){
			return n + x;
		}(1);
	}(2);
	
	cout << c << endl;

	return 0;
}

这样的编程方式叫做 函数式编程, 将所有的代码集中在函数内部, 跟外界影响不大
这样的思维去编程, 叫做函数式编程, 在多线程, 并发. 使用函数式编程, 就可以避免多线程同步的问题
因为它依赖于内部, 天生对多线程, 多核处理程序会更加好

不想立马调用的话

#include <iostream>
using namespace std;
int main(){
	// 	// []捕获列表 ()参数列表 ->返回值
	// auto f = [](int a, int b) -> int{
	// 	// 函数体
	// 	return a + b;
	// };

	// cout << f(1, 2) << endl;

	auto f = [](int n){
		return [n](int x){
			return n + x;
		};
	};

	int c = f(1)(2);
	
	cout << c << endl;

	return 0;
}

lambda表达式实际上是在完成数学上的写法
a d d e r = λ n . ( λ x . ( + x   n ) ) adder = \lambda_n.(\lambda_x.(+ x \ n)) adder=λn.(λx.(+x n))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值