lambda表达式用法

37 篇文章 0 订阅

概述

Lambda 表达式实际上是一个函数,只是它没有名字,叫匿名函数。C++11新增了lambda函数,其基本格式如下:

 [捕捉列表] (参数) mutable -> 返回值类型 {函数体}

一、C++中使用lambda

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

  • []是lambda的引出符,捕捉列表能够捕捉上下文中的变量,来供lambda函数使用:

    [var] 表示以值传递方式捕捉变量var

    [=] 表示值传递捕捉所有父作用域变量

    [&var] 表示以引用传递方式捕捉变量var

    [&] 表示引用传递捕捉所有父作用域变量

    [this] 表示值传递方式捕捉当前的this指针

       还有一些组合:

    [=,&a] 表示以引用传递方式捕捉a,值传递方式捕捉其他变量

       注意:

       捕捉列表不允许变量重复传递,如:[=,a]、[&,&this],会引起编译时期的错误

  • 参数列表与普通函数的参数列表一致。如果不需要传递参数,可以联连同()一同【省略】。
  • mutable 可以取消Lambda的常量属性,因为Lambda默认是const属性;multable仅仅是让Lamdba函数体修改值传递的变量,但是修改后并不会影响外部的变量。
  • ->返回类型如果是void时,可以连->一起【省略】,如果返回类型很明确,可以省略,让编译器自动推倒类型。
  • 函数体和普通函数一样,除了可以使用参数之外,还可以使用捕获的变量。 

 

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

  • [=, &x, &y]表示外部变量 x、y 的值可以被修改,其余外部变量不能被修改;
  • [&, x, y]表示除 x、y 以外的外部变量,值都可以被修改。
[=] (int x, int y) -> bool {return x%10 < y%10; }

例子:

    int a[4] = {5, 2, 9, 4};
    sort(a, a+4, [=](int x, int y) -> bool { return x%10 < y%10; } );
    for_each(a, a+4, [=](int x) { cout << x << " ";} );

 输出结果:5,2,9,4

例子2(用到外部变量):

    #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

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

例子3

 int main(int argc, char* argv[])
 {
      int a = 5, b = 7;
      auto total = [](int x, int y)->int {return x + y; };    //接受两个参数
     cout << total(a, b)<<endl;  //12
      auto fun1 = [=] {return a + b; };   //值传递捕捉父作用域变量
      cout << fun1() << endl; //12
      auto fun2 = [&](int c) {b = a + c; a = 1; };    //省略了返回值类型,引用捕获所有
      fun2(3);    //1 8
     cout << a <<" "<< b << endl;
     a = 5; b = 7;   //被修改后,重新赋值
     auto fun3 = [=, &b](int c) mutable {b = a + c; a = 1; };    //以值传递捕捉的变量,在函数体里如果要修改,要加mutaple,因为默认const修饰
     fun3(3);
     cout << a << " " <<b<< endl;    //5,8
     a = 5; b = 7;   //被修改后,重新赋值
     auto fun4 = [=](int x, int y) mutable->int {a += x; b += y; return a + b; };
     int t = fun4(10, 20);
     cout << t << endl;  //42
     cout << a <<" "<< b << endl;    //5 7
     return 0;
 }

二、Qt中使用lambda

1.总结

     1.Lambda表达式[](){},配合信号与槽使用特别方便,C++11新标准  在.pro 文件里面添加  CONFIG += C++11  之后可以使用。

     2.[]这个方括号是用来传递外部变量的, 因为在匿名函数中是无法使用外部变量的, 只能通过方括号传递给他, 才能捕获到. 比如我需要使用a这个变量,

       只需要在方括号中加入a即可:[a](){};但是如果要传的变量很多, 一个个加到方括号里就太麻烦了, 这时我们可以使用 '=', 将外部所有局部变量、类中

       所有成员以值传递方式传进来: [=] (). 但是通过这种方式传递进来的变量是只读的, 不能修改;

     3.使用 this, 可以把类中所有成员以值传递方式传递进来;[this](){}

     4.使用 &, 把外部所有局部变量, 通过引用方式传递进来(不推荐, 容易出错);

  5.{}花括号内为匿名函数的逻辑代码;

connect(chk, &QCheckBox::clicked, [=](bool checked){
           
                doSomething(i,checked);

connect(pbHB,&QPushButton::clicked,[=](){slotClickedButton(HIGH_B);});

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fyzy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值