C++ 11 匿名函数 (Lambda表达式)说明

新的C++ 11 标准已经向javascript等脚本语言学习了,支持匿名函数,好在笔者对javascript等脚本语言也比较熟悉,所以理解C++的匿名函数也比较容易。

匿名函数是指在一个函数体内的某个功能需要一个定义函数,但是又不想去命名这个函数的场合下现场即时定义的表达式,也就是指Lambda表达式,用于简化编程工作。

定义匿名函数的语法

[capture] (parametersspecifiers ->return_type { body }

现对该语法的各个部分解释如下:

1、 [capture] 捕获的外部变量列表

标示一个Lambda表达式的开始,必须存在,不能省略。通过逗号分隔各个捕获参数,可进行传值捕获或者引用捕获,lambda表达式与这些捕获的外部变量会构成一个闭包(Closure),外部变量为闭包的成员变量。capture参数对象只能使用那些定义Lambda
为止时Lambda所在作用范围内可见的局部变量(包含Lambda所在类的this指针)   

#语法示例说明
1[]没有任何capture参数对象,但不能省略
2[=]以值传递方式捕获Lambda所在范围内的所有局部变量。
3[&]以引用传递方法捕获Lambda所在范围内的所有局部变量。
4this函数体可以使用Lambda所在类的成员变量。在类的非静态成员函数中定义的lambda表达式可以通过捕捉this指针,来访问对象的成员变量和成员函数
5[a,&b]a以值传递捕获,b以引用形式捕获。
6[=,&c]c以引用形式捕获,其他变量以值传递捕获。
7[&,x]x以值传递形式捕获,其他变量以引用形式捕获。

① 全局变量、静态变量不用显示写在外部变量列表中,可直接在lambda表达式中读写
② 传值捕获的外部变量是一个副本,默认情况下在lambda表达式中是只读的,若想修改该副本,需要在lambda表达式上添加mutable关键字  如:auto a2 = [Value](int x) mutable {Value++;}; 

2、(parameters):函数参数

参数列表,标识重载的()操作符,若lambda函数没有形参且没有被mutable等修饰,则参数的空圆括号可以省略,但笔者建议即使没有参数,括号不要省略,这样便于阅读代码。参数可以使用值传递和引用传递,与普通的函数参数没有区别。
与普通函数相比,lambda表达式的参数有如下限制
① 参数不能有缺省值   如:int Add1(int a, int b=10) 
② 不能有可变长参数列表  如:int  Add2(int count, ...)
③ 不能有无名参数  如:int Add3(int a, int b, int) 

3、specifiers :mutable或者exception声明

可以省略。按函数参数按值传递时,加上mutable修饰后,可以修改传递进来的拷贝。
  exception声明用于指定函数抛出的异常,可以使用throw(int)。

4、->return_type :返回值类型

标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方时,这部分可以省略。

5、{ body }:匿名函数体

匿名函数的实现代码,以一对大括号包围,不能省略,函数体大括号内部可以为空。

6、示例

// 隐式返回类型
[](int x,int y) {return x+y;} 

//没有return语句,Lambda的函数返回类型为 'void'
[](int& x) {++x;}

// 没有参数,访问全局变量num
[]() {++num;}

//省略参数
[] {++num;}

实例:

例如,在一个应用中,需要用库函数sort排序,sort行数需要有一个比较回调,当一个程序中,排序函数用的次数不多时,专门给排序回调函数起个名字污染命名空间似乎不合算,能不能不给它起cmp的名字,又能使用比较大小的功能呢?此时就可以使用匿名函数了。

#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm> //for sort

int sort_test()
{
	std::vector<int> data = { 6, 1, 12, 3, 14, 16, 8, 9 };

	//from big to small
	sort(data.begin(), data.end(), [](int& a, int& b)->bool {
		return a > b;
	});

	cout << "Big->Small: ";
	for (auto i : data)
		cout << i << " ";
	cout << endl;

	//from small to big
	sort(data.begin(), data.end(), [](int& a, int& b)->bool {
		return a < b;
	});

	cout << "Small->Big: ";
	for (auto i : data)
		cout << i << " ";
	cout << endl;

	return 0;
}

int main(int argc,char * argv[])
{
    sort_test();

    return 0;
}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值