C++ lambda表达式

与函数类似,lambda表达式也是一种可调用对象,但其可以定义在函数内部。《C++ Primer》中提到一个lambda表达式表示一个可调用的代码单元,可以将其理解为一个未命名的内联函数。本笔记参考《C++ Primer》,主要对C++ lambda表达式的用法进行一个简单的记录。

用法简介

当需要一个实现简单功能的可调用对象时,使用lambda表达式可以使得代码更为简洁。在一些泛型算法中可以直接传入lambda表达式自定义规则,比如sort第三个参数直接写个lambda表达式指定排序规则。

lambda表达式的形式如下:

[capture list](parameter list) -> return type {function body}

[捕获列表](参数列表) -> 返回类型 {函数体}

捕获列表用来放置在lambda表达式所在函数中定义的需要传入lambda表达式的局部变量。其余部分的含义与函数定义中对应的部分相同。不过lamdba必须使用尾置返回。lambda表达式中,参数列表和返回类型可以省略,捕获列表(尽管可能为空)和函数体必须存在。调用lambda表达式的方法也与调用普通函数一样,使用调用运算符()即可。

简单示例

简单的lambda表达式及调用示例如下,该示例捕获列表为空,没有参数列表和返回类型,函数体也仅仅是返回一个字符串。

auto fun = [] { return "Hello world!"; };
cout << fun() << endl;//输出Hello world!

参数传递

lambda表达式传递参数的方式也与函数类似,使用给定实参初始化形参,通常实参和形参类型必须匹配。下面给出一个示例。

auto fun = [](const string &s1, const string & s2) { return s1 + ' ' + s2; };
string s1 = "Hello";
string s2 = "world";
cout << fun(s1,s2) << endl;//输出Hello world

捕获列表的使用

通过捕获列表,我们可以在lambda表达式中使用lambda表达式所在函数中定义的局部变量。

值捕获和引用捕获

采用值捕获,被捕获的变量的值是在lambda创建时拷贝。下面的示例中,变量a在lambda创建时被捕获,完成了值的拷贝,因此当a的值改变后,再调用lambda发现并不起作用。

int a = 1;
auto fun = [a](int b) { return a + b; };
int b = 1;
cout << a << ' ' << b << endl;//输出1 1
cout << fun(b) << endl;//输出2
a += 1;
cout << a << ' ' << b << endl;//输出2 1
cout << fun(b) << endl;//输出2

引用捕获的示例如下

int a = 1;
auto fun = [&a](int b) { return a + b; };
int b = 1;
cout << a << ' ' << b << endl;//输出1 1
cout << fun(b) << endl;//输出2
a += 1;
cout << a << ' ' << b << endl;//输出2 1
cout << fun(b) << endl;//输出3

隐式捕获

使用隐式捕获,就可以不显式列出要在lambda表达式要捕获的变量,取而代之的是让编译器通过lambda表达式中的代码来推断使用的变量。在捕获列表中写个=指示使用值捕获方式,写个&指示使用引用捕获方式。

int a = 1;
auto fun = [=](int b) { return a + b; };//[]中写个=,使用值捕获方式
int b = 1;
cout << a << ' ' << b << endl;//输出1 1
cout << fun(b) << endl;//输出2
a += 1;
cout << a << ' ' << b << endl;//输出2 1
cout << fun(b) << endl;//输出2
int a = 1;
auto fun = [&](int b) { return a + b; };//[]中写个&,使用引用捕获方式
int b = 1;
cout << a << ' ' << b << endl;//输出1 1
cout << fun(b) << endl;//输出2
a += 1;
cout << a << ' ' << b << endl;//输出2 1
cout << fun(b) << endl;//输出3

可以混用显式捕获和隐式捕获。不过若隐式部分使用值捕获方式,则显式部分就不能用值捕获方式,反之,隐式部分使用引用捕获方式,则显式部分就不能用引用捕获方式。

int a = 1;
int b = 1;
auto fun = [&, b](int c) { return a + b + c; };
int c = 1;
cout << fun(b) << endl;//输出3

显式捕获和隐式捕获用同一种方式提示错误:
在这里插入图片描述
在这里插入图片描述
当然,要是不用隐式捕获,捕获列表中各变量的捕获方式就随便写。

尾声:就简单记录这么多,一般我自己也很少用到复杂的情况。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值