C++ 中的Lambda表达式写法

2020-01-06 16:37:34王冬梅

小喵的唠叨话:

寒假之后,小喵在家里无所事事,最近用C++写代码的时候,用到了std::sort这个函数,每次用这个函数,小喵似乎都得查一下lambda表达式的写法。正好最近很闲,不如总结一下。

在Bing上搜索 C++ lambda ,第一条记录就是MSDN上的C++ lambda的介绍。本文也是基于这篇文章来写的。

那么接下来,我们分几个部分来介绍。

一、什么是Lambda表达式

MSDN上对lambda表达式的解释:

在 C++ 11 中,lambda 表达式(通常称为 “lambda”)是一种在被调用的位置或作为参数传递给函数的位置定义匿名函数对象的简便方法。 Lambda 通常用于封装传递给算法或异步方法的少量代码行。 [1]

看了这个解释,相信大家已经理解lambda表达式是什么。简而言之,lambda表达式就是一种定义函数的简单的方法。

举一个简单的例子:求一个数的阶乘。

这是一般的函数的写法:


// 这里要求n>=0,同时n的取值不能太大,会溢出
// 为了方便,这里并没有处理上面说到的问题
int factorial(int n) {
 int fact = 1;
 for (int i = 1; i <= n; ++ i) fact *= i;
 return fact;
}

Lambda表达式的写法:


autofactorial = [](int n) {
 int fact = 1;
 for (int i = 1; i <= n; ++ i) fact *= i;
 return fact;
};

乍一看,这两种定义方式十分的相似。但其实这是两种完全不同的方式,前一种是函数定义式,而后一种是一个表达式。factorial是变量名,等于号后面的是值,也就是一个lambda表达式,本质上是一个匿名的函数。最终factorial就是一个函数。

很多时候,我们只是直接书写lambda表达式,而不需要给他一个名字。比如排序的时候,sort可以接受一个自定义的比较函数,这时候直接书写lambda表达式即可。

二、Lambda表达式的作用

由于lambda本身其实也就是一种函数的定义方式。因此它的主要作用还是和一般函数一样。但是lambda表达式相对于一般函数,又有一些功能之外的作用。参考了知乎上的一些回答 [2] ,小喵也进行了总结。

1、可以用表达式来定义函数,这样使得函数的定义和调用在一起,语意和逻辑上更为紧凑。同时,对于只是用一次的短小的函数,直接调用匿名的lambda表达式是最好的选择,这样就不需要给每个函数起名字了。 /* 起名字一直是一个很令人头疼的问题 */

2、闭包(Closure)。这个小喵的写javascript的时候时常会用到。闭包本质上就是能够访问上下文环境中变量的代码块。

这里我们简单的举个例子,还是之前的求阶乘的问题,现在我们有些提高需求。

现在需要完成下面的三种阶乘的运算: