zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    2019年技能学习计划
    EVM项目管理
    常用LINQ关键字用法汇总
    如何让Enum枚举实现异或操作
    使用COM打开Excel文档注意事项
    C#使用NPOI读写Excel的注意事项
    应用国际化多语言化实现方法
    DLL简单分析与调用方法
    C#读写Excel实践笔记
    Vue基础开发笔记
  • 原文地址:https://www.cnblogs.com/whiteBear/p/12609212.html
Copyright © 2011-2022 走看看