Lambda表达式

Lambda表达式

匿名函数有函数体,但没有函数名。
匿名函数是很多高级语言都支持的概念,如lisp语言在1958年首先采用匿名函数。正因为如此,C++11也同样引入了lambda函数。
在C++11中,你可以在源码中内联一个lambda函数,这就使得创建快速的、一次性的函数变得简单了。

相同类似功能我们也可以使用函数对象或者函数指针实现:函数对象能维护状态,但语法开销大,而函数指针语法开销小,却没法保存范围内的状态。lambda表达式正是结合了两者的优点。

声明Lambda表达式

[capture list] (params list) mutable exception-> return type { function body };
[capture list] (params list) -> return type {function body};  //1
[capture list] (params list) {function body};		//2
[capture list] {function body};		//3

   
   
  • 1
  • 2
  • 3
  • 4
  • capture list:捕获外部变量列表
  • params list:形参列表
  • mutable指示符:用来说用是否可以修改捕获的变量
  • exception:异常设定
  • return type:返回类型
  • function body:函数体

标号1. 函数声明了一个const类型的表达式,此声明不可改变capture list中的捕获的值。
标号2. 函数省略了返回值,此时如果function body内含有return语句,则按return语句返回类型决定返回值类型,若无则返回值为void类型。
标号3. 函数无参数列表,意味无参函数。

简单的例子

在C++中我们对STL库中的sort()运用十分频繁,接下来就是关于他的一个例子:

//省略细节
bool compare(int a,int b){
	return a<b;
}
{
	vector<int> vec{1,0,9,5,3,3,7,8,2};
	sort(vec.begin(),vec.end(),compare);
	//在C++11之前,我们使用STL的sort函数,可以提供一个谓词函数来为sort改变其排序判断标准
}

   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

接下来是lambda表达式的形式:

{	
	vector<int> vec{1,0,9,5,3,3,7,8,2};
	sort(lbvec.begin(), lbvec.end(), [](int a, int b) -> bool { return a < b; });  
	 // Lambda表达式
}

   
   
  • 1
  • 2
  • 3
  • 4
  • 5

lambda不仅提高了代码可读性,且在例子中,这一个提供判断依据的函数是只需调用一次,在这时,lambda表达式就显示出它的“即用即扔”的特点,很适合这种不需要重复调用且运用区域单一的情景(而不是去多写一个compare的函数)。

捕获外部变量

Lambda表达式可以捕获外面变量,但需要我们提供一个谓词函数([capture list]在声明表达式最前)
类似参数传递方式:值传递、引入传递、指针传递。
在Lambda表达式中,外部变量捕获方式也类似:值捕获、引用捕获、隐式捕获

值捕获

    int a = 123;
    auto f = [a] { cout << a << endl; }; 
    f(); // 输出:123
    a = 321;
    f(); // 输出:123

   
   
  • 1
  • 2
  • 3
  • 4
  • 5

值捕获和参数传递中的值传递类似,被捕获的值在Lambda表达式创建时通过值拷贝的方式传入,因此Lambda表达式函数体中不能修改该外部变量的值;同样,函数体外对于值的修改也不会改变被捕获的值。

引用捕获

    int a = 123;
    auto f = [&a] { cout << a << endl; }; 
    a = 321;
    f(); // 输出:321

   
   
  • 1
  • 2
  • 3
  • 4

引用捕获的变量使用的实际上就是该引用所绑定的对象,因此引用对象的改变会改变函数体内对该对象的引用的值。

隐式捕获

隐式捕获有两种方式,分别是
[=]:以值补获的方式捕获外部所有变量
[&]:表示以引用捕获的方式捕获外部所有变量

	int a = 123 ,b=321;
    auto df = [=] { cout << a << b << endl; };    // 值捕获
    auto rf = [&] { cout << a << b << endl; };    // 引用捕获

   
   
  • 1
  • 2
  • 3

其他捕获方式

C++11Lambda表达式捕获外部变量形式
[ ]不捕获任何变量(无参函数)
[变量1,&变量2, …]值(引用)形式捕获指定的多个外部变量
[this]值捕获this指针
[=, &x]变量x以引用形式捕获,其余变量以传值形式捕获

Lambda表达式的参数

  • 参数列表中不能有默认参数
  • 不支持可变参数
  • 所有参数必须有参数名
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值