您的位置:首页 > 编程语言 > C语言/C++

lambda表达式的实质——什么是lambda表达式,为什么要使用lambda表达式

2015-11-09 22:49 531 查看
lambda表达式是C++ 11的新特性。它是一个匿名函数,但是又跟函数不同。要想理解lambda表达式,特别是为什么要使用lambda表达,首先要理解回调函数。如果不太理解回调函数请戳这里。简而言之,回调函数就是被作为参数供另一个函数调用的函数(注意不是函数的返回值被另一个函数调用,而是函数的指针或者说代码被另一个函数调用)。比如void
funcA(int i, bool (*funcB)(int))。 这里函数funcA有两个参数,一个是i,另一个就是函数funcB的指针。我们知道在声明一个函数时,函数参数的数据类型就确定了。所以如果要调用funcA,那么我们传递给它的参数必须是两个,一个是整型,另一个是以整型为参数以布尔型为返回值的函数类型(函数的类型由它的参数类型和返回值类型决定)。所以,我们在实现回调函数funcB时,必须按照这个参数和返回类型来实现。这就会带来一定的局限性。比如,我想让我的函数funcB更具普适性,让它多带一个参数以适应不同的情况,变成bool
myFuncB(int i, int j)。那么它就不能作为参数被funcA调用了。这时lambda表达式就可以粉墨登场了。lambda表达式语法如下所示:

[capture list](parameter list)->return type{function body}
其中,参数列表和返回类型都可以省略。捕获列表也可以为空,但是[]必须写上。可见lambda表达式区别于普通函数,除了没有函数名外,还多了一个捕获列表。它之所以能解决我们之前所说的那个局限性就全靠这个捕获列表。捕获对象和参数的区别在于,捕获对象的值在程序运行到lambda表达式之前就已经确定了。而参数的值在运行到lamdba表达式之前是不确定的。举个栗子:

void fun()
{
int i=1;
int j=2;

funcA(i, [j](int k){return k>j;});
}
当程序运行funcA之前,j的值就确定了,而k的值是不确定的。k的值只有在funcA函数里面真正调用lambda表达式的时候才确定。这个程序还可以换一种更加明确的写法。

void fun()
{
int i=1;
int j=2;
function<bool(int)> f=[j](int k)(return k>j;);

funcA(i, f);
}
当程序运行到创建f对象时,j的值是确定的(它其实被作为f的一个成员变量初始化了),而k的值是不确定的。注意lambda表达式是一种特殊的数据类型(即使它和某函数具有相同参数类型和返回值类型,它们也属于不同数据类型),编译器在编译的过程中会根据我们所写的lambda表达式自动产生一个数据类型。所以声明f对象的时候我们一般只能用auto f=[j](int k)(return k>j),因为我们不知道它是什么类型。但是我们之前说过回调函数的类型在声明调用者的时候(也就是声明funcA的时候)就已经确定了。所以这里有点矛盾。这个矛盾需要另一个库模版函数类型funcion来解决。有了它,只要参数和返回值类型都相同就可以定义为同一种function类型。

lambda表达式可以解决回调函数 的参数适配问题。但是毕竟lambd表达式只能表达少量代码。当代码一多,用lambda表达式就很难看了。这时我们就需要另一个工具,叫做bind。欲知详情请戳这里

水平有限,如有不妥,敬请拍砖!

参考文献

C++ Primer
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ lambda表达式