• C++入门 -- lambda表达式


    lambda表达式(匿名函数)的组成:

    1. 捕获子句(在 c + + 规范中也称为lambda 引导)。

    2. 参数列表可有可无. (也称为lambda 声明符

    3. 可变规范可有可无.

    4. 异常规范可有可无.

    5. 尾随-返回类型可有可无.

    6. lambda 体

    lambda表达式以一对中括号开始,和函数定义一样,会有参数列表,有一个函数体,里面会有return语句

    Lambda表达式一般不需要说明返回值(相当于auto),有特殊情况需要说明时,则应使用‘->’

    每个lambda表达式都有一个全局唯一的类型,要精准捕捉lambda表达式到一个变量中,只能通过auto声明的方式

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <vector>
     4 
     5 using namespace std;
     6 
     7 int Foo(int a, int b) {
     8     return a+b;
     9 }
    10 
    11 int main() {
    12     //  []捕获列表  ()参数列表  ->返回值
    13     int c = [](int a, int b) ->int{
    14         //函数体
    15         return a+b
    16     }(1, 2);
    17     
    18     //f为自动推导后的函数体类型
    19     auto f = [](int a, int b) ->int{
    20         //函数体
    21         return a+b
    22     };
    23     
    24     c = f(1, 2);
    25         
    26     return 0;
    27 }
    lambda作者认为所有的程序都可以归纳为lambda表达式,变为一个函数式
    ...
        //lambda作者认为所有的程序都可以归纳为lambda表达式,变为一个函数式
        //lambda表达式内部可以嵌套 -- 函数式编程:
        int c = [](int n){
            return [](int x){
              return n+x;  
            }(1);
        }(2);
        cout << c << endl;
        
        auto f = [](int n){
            return [](int x){
              return n+x;  
            };
        };
        int c = f(1)(2);
        cout << c << endl;
    ...

    mutable关键字

    mutable关键字,表示可以修改按值传入的变量的副本(不是值本身),类似于不带const关键字的形参。使用mutable关键字后对按值传入的变量进行的修改,不会将改变传递到Lambda表达式之外。

    例子:

    int main() {
        int t = 10;
        auto f = [t]() {
            return ++t;
        };
    
        return 0;
    }

    error: cannot assign to a variable captured by copy in a non-mutable lambda

    在捕获列表中,只是捕获了外界的t,在表达式内部,t还是const类型,不允许修改

    ...
    int main() {
        int t = 10;
        auto f = [t]() mutable{
            return ++t;
        };
        cout << f() << endl;
        cout << f() << endl;
        cout << t   << endl;
        return 0;
    }

    out:

    t不会改变,因为i修改的是按值传入的副本,不会影响值本身。 

    为什么两次调用f(),返回值会传递。

    捕获列表

    捕获列表,可以理解为一个参数的类型,默认情况下lambda表达式内部在默认情况下是不能使用函数外部的变量,

    捕获列表就可以起到传递外部数据的作用:

    • [] 不捕获任何变量。
    • [&] 捕获外部作用域中所有变量,并作为引用在函数体中使用(按引用捕获)。
    • [=] 捕获外部作用域中所有变量,并作为副本在函数体中使用(按值捕获)。
    • [=,&foo] 按值捕获外部作用域中所有变量,并按引用捕获 foo 变量。
    • [bar] 按值捕获 bar 变量,同时不捕获其他变量。
    • [this] 捕获当前类中的 this 指针,让 lambda 表达式拥有和当前类成员函数同样的访问权限。如果已经使用了 & 或者 =,就默认添加此选项。捕获 this 的目的是可以在 lamda 中使用当前类的成员函数和成员变量。
        //进阶写法
        for_each(v.begin(), v.end(), [](int n) {
            if(v[i] % 2 == 0) {
                cout << v[i] << "是偶数" <<endl;
            }else{
                cout << v[i] << "是奇数" <<endl;            
            }
        });
  • 相关阅读:
    从开心网的奴隶安抚与折磨想到员工积极性与人力成本的问题
    悲剧的做网站的,我们都没有认真的前行
    如何做生意
    Android Market中产品图标设计原则
    控制UpdataPanel中的GridView模板列控件同步刷新
    DataTable筛选
    IE6,7,8,FF兼容总结
    DevPress Grid 设置行样式
    SQL分组查询
    DevexPress checkedit 多选解决方案(原创)
  • 原文地址:https://www.cnblogs.com/y4247464/p/13935743.html
Copyright © 2020-2023  润新知