浅谈c++中的Lambda表达式

浅谈c++中的Lambda表达式,第1张

Lambda作为c++11新特性之一,受到无数程序员的青睐。
1、Lambda的由来
我们往往会遇到一下两个问题:

1、使用STL时往往会用到大量函数对象,为此需要编写很多函数对象类,而且很多函数对象只使用一次,编写这样的函数对象有点浪费;
2、或者在全局函数中调用一些较为简单的函数,例如double转换为string:
string convertToString(double d) 
{
	ostringstream os;
	if (os << d)
		return os.str();
	return "invalid conversion";
}
我们这个在全局函数中定义该函数,污染了全局函数空间,而且该函数可能只用一次,完全没有必要在全局函数中定义。

于是,为了解决以上问题,Lambda横空出世,有个简单例子:

vector<int>vec={12,14,35,67};
int count = count_if(vec.begin(),vec.end(),[](int x){return x % 2 == 0;}   

直接用Lambda表达式替换以下函数:

bool fun7(int x){return x%2 == 0;}

2、Lambda的定义以及使用
(1)语法形式:

[ capture ] ( params ) opt -> ret { body; };

其中carpture是捕获列表,params是参数,opt是选项(.opt表示lambda的选项,例如mutable),ret则是返回值的类型,body则是函数的具体实现。(其中返回值可有有无)

(2)常见的捕获列表的说明
capture:外部变量访问方式说明符

[] :表示不捕获任何变量,也就是没有使用任何函数对象参数
[=]:表示按值捕获变量,外部的变量不允许被修改
[&]:表示按引用捕获变量,外部的变量允许被修改
[this]:值传递捕获当前的this

关于[=]的简单使用:
其在Qt中信号槽中用的比较多,如下:

connect(ui.actionopen, &QAction::triggered, [=]()mutable {……});

这里的Lambda相当于一个匿名函数,而也可以调用其函数名,如下:相当于调用函数f();

#include 
using namespace std;
int main()
{
	int a = 5,b = 6;
	auto f = [=](){return a*b;};//[=]按值捕获了a和b
	cout << f() << endl;
	return 0;
}

上面这种不能修改外部变量a与b的值,当然你想要在Lambda函数体内修改外部变量值,也可以通过
mutable(注意是能修改拷贝,而不是值本身):

#include 
using namespace std;
int main()
{
	int a = 5;
	auto f = [=]()mutable {return a *= 5; };//取消常量性
	cout << f() << endl;
	cout << a << endl;
	system("pause");
	return 0;
}

输出如下:

当然也可以[&]来达到目的:

#include 
using namespace std;
int main()
{
	int a = 5;
	auto f = [&]()mutable {++a; return a; };//取消常量性
	cout << f() << endl;
	cout << a << endl;
	system("pause");
	return 0;
}

输出如下:

3、注意事项:
(1)重复捕获:

[=,x]

其中x被重复捕获,因为=表示按值的方式捕获所有的变量。
(2)[=]:按值捕获某个变量相当于在表达式内部已经生成了一个被捕获变量的副本,原本的变量再怎么变化都不会影响到副本的值,如下:

#include 
using namespace std;
int main()
{
	int a = 10;
	auto f = [=] {return a + 1; };//按值捕获a
	cout << f() << endl;
	a++;
	cout << f() << endl;
	system("pause");
	return 0;
}

输出结果:

4、使用Lambda的好处:
由以上例子,我们不难看出

1、lambda函数比较轻便,即用即扔,很适合需要完成某一项简单功能,但是这个简单的功能只在此一处使用,连名字都很随意的情况下;

2、lambda是匿名函数,一般用来给filter,map,reduce这样的函数式编程服务,充当于函数对象的作用;

3、作为回调函数,可以传递给某些应用,比如消息处理等,特别是在Qt中的应用极为广泛。

当然,关于Lambda表达式还有很多知识点与相关应用,特别是其与模板编程的结合,由于笔者知识浅显只能说这么多了。
参考链接以及书籍:
《新标准C++程序设计》——郭炜
https://www.csdn.net/tags/MtjaEgysNTA4NzAtYmxvZwO0O0OO0O0O.html
https://blog.csdn.net/weixin_43055404/article/details/103299156

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1499207.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-25
下一篇 2022-06-25

发表评论

登录后才能评论

评论列表(0条)

保存