C++11 Lambda表达式(匿名函数)详解


使用STL时,往往会大量用到函数对象,为此要编写很多函数对象类。而有的函数对象类只用定义一个对象,而且这个对象也只使用一次,那编写这样一个函数对象就很浪费了。而且有时这定义函数对象类的地方和使用函数对象的地方很远,不方便查看。
那对于使用一次的函数对象类,能不能直接在使用它的地方定义呢?lambda就是为解决这个问题而提出的(其实在python、C#等中匿名函数已存在很久了)。使用Lambda表达式可以减少程序中函数对象类的对象,使程序更加优雅。


Lambda表达式的定义形式:
[外部变量访问方式说明符] (参数表) -> 返回值类型
{
   语句块
}

说明:“外部变量访问方式说明符”可以是=&,表示{}中用到的、定义在{}外面的变量在{}中是否允许被改变。= 表示不允许,&表示允许。当然,在{}中也可以不使用定义在外面的变量。“->返回值类型”可以省略

  • 举个栗子:
[=] (int x, int y) -> bool {return x%10 < y%10; }
  • 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 的大小。这样,就不用专门编写一个函数对象类了。
  • 第 3 行,for_each 的第 3 个参数是一个 Lambda 表达式。for_each 执行过程中会依次以每个元素作为参数调用它,因此每个元素都被输出。
  • 再举个例子:用到外部变量的Lambda表达式的程序:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
    int a[4] = { 1, 2, 3, 4 };
    int total = 0;
    for_each(a, a + 4, [&](int & x) { total += x; x *= 2; });
    cout << total << endl;  //输出 10
    for_each(a, a + 4, [=](int x) { cout << x << " "; });
    return 0;
}

输出结果:
10
2 4 6 8

程序分析:

  • 第 8 行,[&]表示该 Lambda 表达式中用到的外部变量 total 是传引用的,其值可以在表达式执行过程中被改变(如果使用[=],编译无法通过)。该 Lambda 表达式每次被 for_each 执行时,都将 a 中的一个元素累加到 total 上,然后将该元素加倍。

实际上,“外部变量访问方式说明符”还可以有更加复杂和灵活的用法。例如:

  • [=, &x, &y]表示外部变量 x、y 的值可以被修改,其余外部变量不能被修改;
  • [&, x, y]表示除 x、y 以外的外部变量,值都可以被修改。

参考:http://c.biancheng.net/view/433.html

原文地址:https://www.cnblogs.com/whiteBear/p/12609212.html