C++11-lambda表达式

1.基本使用

Lambda函数也就是一个函数,它的语法定义如下:
                [捕获列表](参数列表) mutable ->返回类型{函数体}

捕获列表    允许访问当前作用域下的某一个变量,可以为空(方括号不能省略)
参数列表    Lambda表达式的参数,可以省略(包括括号),不能有不定参数,不能有默认参数,参数必须有名称
mutable    捕获列表中的变量默认以const方式传递,不能修改,添加此关键字能指定变量可以被修改
类型    指定返回值类型(如果返回类型比较明显,可以省略,让编译器自动推断,省略时要连同->符号一起省略),包括void类型
函数体    需执行的代码,如果没有return语句且没指定类型,默认返回类型为void

捕获列表的说明如下

捕获形式    捕获类型    说明
[]    不捕获    不捕获外部变量
[变量名, …]    显式捕获    默认以值得形式捕获指定的多个外部变量(用逗号分隔),如果引用捕获,需要显示声明(使用&说明符)
[this]    显式捕获    以值的形式捕获this指针
[=]    隐式捕获    以值的形式捕获所有外部变量
[&]    隐式捕获    以引用形式捕获所有外部变量
[=, &x]    混合捕获    变量x以引用形式捕获,其余变量以传值形式捕获(注意顺序不能变,=符号一定要在前面)
[&, x]    混合捕获    变量x以值的形式捕获,其余变量以引用形式捕获(注意顺序不能变,&符号一定要在前面)
 

#include <iostream>
#include <string>

#include <stdio.h>
int main(int argc, char* argv[])
{
    int a = 10, b = -1;

    // 显式捕获,是以const方式传递,无法改变捕获值
    auto f1 = [a, b]{ std::cout<<"f1 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();};
    f1();

    // 显式的值捕获,正常,注意此时()一定要加,不然依旧给你报错,
    auto f2 = [a, b]()mutable{ a = 100; b = -10;std::cout<<"in f2 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();};
    f2();

    //修改的捕获值值,表达式外捕获值还是原值
    std::cout<<"after f2 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();

    // 显式的引用捕获
    auto f3 = [&a, &b]{ a = 200; b = -20; std::cout<<"in f3 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();};
    f3();
    std::cout<<"after f3 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();

    // 隐式的值捕获,报错,无法改变捕获值
    //auto f4 = [=]{ a = 100; b = -10; };

    // 隐式的值捕获,正常
    auto f5 = [=]()mutable{ a = 300; b = -30; std::cout<<"in f5 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();};
    f5();
    std::cout<<"after f5 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();

    // 隐式的引用捕获,正常
    auto f6 = [&]{ a = 400; b = -40;std::cout<<"in f6 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush(); };
    f6();
    std::cout<<"after f6 "<<"a:"<<a<<" b:"<<b<<std::endl;std::cout.flush();

    // 混合捕获
    auto f7 = [=, &a]{ a = 500;std::cout<<"in f7 "<<"a:"<<a<<std::endl;std::cout.flush(); };
    f7();
    std::cout<<"after f7 "<<"a:"<<a<<std::endl;std::cout.flush();
    // 混合捕获,a是值传递,需要加mutable
    //auto f8 = [&, a]{ a = 100; };

    // 混合捕获,表达式外捕获值还是原值
    auto f9 = [&, a]()mutable{ a = 600; std::cout<<"in f9 "<<"a:"<<a<<std::endl;std::cout.flush(); };
    f9();
    std::cout<<"after f9 "<<"a:"<<a<<std::endl;std::cout.flush();
}

使用lambda表达式时间有些需要主义的问题,

    int j = 10;
    auto by_val_lambda = [=]{ return j + 1; }; //返回值 11
    auto by_ref_lambda = [&]{ return j + 1; };//返回值 11
    std::cout<<"by_val_lambda: "<<by_val_lambda()<<std::endl;//输出11
    std::cout<<"by_ref_lambda: "<<by_ref_lambda()<<std::endl;//输出11

    j=12;
    std::cout<<"by_val_lambda: "<<by_val_lambda()<<std::endl;//输出11
    std::cout<<"by_ref_lambda: "<<by_ref_lambda()<<std::endl;//输出13

捕获值得的捕获方法,值按常量传递进来,不会随着包含lambda表达式函数中的赋值而改变。

2.stl与lambda表达式组合使用

#include <vector>
#include <iostream>
int main(int argc, char *argv[])
{
    std::vector <int> v={1,2,3,4,5,6,7};
    int count1=0;
    std::for_each(v.begin(),v.end(),[&count1](int value){if(value>2){++count1;}});
    std::cout<<"count1:"<<count1<<std::endl;
    int count2=std::count_if(v.begin(),v.end(),[](int value){return value>2;});
    std::cout<<"count2:"<<count2<<std::endl;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值