本文中的一些重要概念摘自C语言中文网
链接:http://c.biancheng.net/view/433.html

介绍lambda表达式之前,我们先来温习一下函数对象是啥
如果一个类对()运算符进行了重载,那么这个类就叫做函数对象类,由函数对象类创建出来的对象就叫做函数对象,因为使用函数对象的时候调用重载的()成员函数时像极了函数调用,因而得名。具体情况参见我的博客对函数对象介绍的章节:
链接:https://blog.nowcoder.net/n/82f3362299a24fa4850cd4a71004262c

我们的lambda表达式就是用来实现那些只用一次的函数对象类的,这样就不会造成“定义的函数对象类只使用一次”的“浪费”情况。同时lambda表达式实现了“在定义的地方使用”,使用 Lambda 表达式可以减少程序中函数对象类的数量,使得程序更加优雅。

lambda表达式的格式:Lambda 表达式的定义形式如下:
[外部变量访问方式说明符] (参数表) -> 返回值类型
{
语句块
}
其中,“外部变量访问方式说明符”可以是=或&,表示{}中用到的、定义在{}外面的变量在{}中是否允许被改变。=表示不允许,&表示允许。当然,在{}中也可以不使用定义在外面的变量。“-> 返回值类型”可以省略,也就是可以没有返回值。

下面是一个合法的Lambda表达式:
[=] (int x, int y) -> bool {return x%10 < y%10; }
=表示x,y不允许被改变,这个Lambda表达式返回x%10 < y%10表达式值的真假。
这样看来写lambda表达式就和我们编写一个函数差不多了,只不过函数头(返回值,参数表等)有点不太一样。

Lambda 表达式实际上是一个函数,只是它没有名字。下面的程序段使用了上面的 Lambda 表达式:
int a[4] = {11, 2, 33, 4};
sort(a, a+4, [=](int x, int y) -> bool { return x%10 < y%10; } );
for_each(a, a+4, [=](int x) { cout << x << " ";} );
这段程的输出结果是:
11 2 33 4

程序第 2 行使得数组 a 按个位数从小到大排序。具体的原理是:sort 在执行过程中,需要判断两个元素 x、y 的大小时,会以 x、y 作为参数,调用 Lambda 表达式所代表的函数,并根据返回值来判断 x、y 的大小。这样,就不用专门编写一个函数对象类了。

下面是具体代码:

#include<iostream>
#include<algorithm>

using namespace std;

int main()
{
    int a[] = {11, 12, 19, 25};
    sort(a, a+4, [=](int x, int y) -> bool { return x%10 < y%10; });
    for_each(a, a+4, [=](int x) { cout << x << " ";});
    cout << endl;
    return 0;
}

测试程序输出结果:
图片说明
从运行结果可以看出,这个lambda表达式实现了,比较整型数字的个位数字的大小,之后作为sort函数的排序依据。

接下来再尝试一个使用了外部变量的lambda表达式:
部分源码还是在上面源码中出现过的:

#include<iostream>
#include<algorithm>

using namespace std;

int main()
{
    int a[] = {11, 12, 19, 25};
    sort(a, a+4, [=](int x, int y) -> bool { return x%10 < y%10; });
    for_each(a, a+4, [=](int x) { cout << x << " ";});
    cout << endl;

    cout << "calc sum:" << endl;
    int b[] = {1, 2 , 3, 4 ,5};
    int total = 0;
    for_each(b, b+5, [&] (int x) { total += x; });
    for_each(b, b+5, [=](int x) { cout << x << " "; });
    cout << "total value:" << total << endl;
    return 0;
}

对于b这个数组,我使用了一个标记为&的lambda表达式来实现累加,使其可以使用lambda表达式外面的变量total,并对其进行修改。

实际上,“外部变量访问方式说明符”还可以有更加复杂和灵活的用法。例如:
[=, &x, &y]表示外部变量 x、y 的值可以被修改,其余外部变量不能被修改;
[&, x, y]表示除 x、y 以外的外部变量,值都可以被修改。