• lambda表达式


    lambda表达式是C++11最重要也是最常用的一个特性之一。

    lambda表达式有如下优点

    • 声明式编程风格:就地匿名定义目标函数或函数对象,不需要额外写一个命名函数或者函数对象。以更直接的方式去写程序,有好的可读性和维护性
    • 简洁:不需要额外再写一个函数或者函数对象,避免了代码膨胀和功能分散,让开发者更加集中精力主手边的问题,同时也获取了更高的生产率。
    • 在需要的时间和地点实现功能必报,使程序更灵活

    lambda表达式的概念和基本用法

    lambda表达式定义了一个匿名函数,并且可以捕获一定范围内的变量,其语法形式可归纳为:

    [capture] (params)opt->ret {body;};

    lambda表达式可以通过捕获列表捕获一定范围内的变量:

    • [] 不捕获任何变量
    • [&] 捕获外部作用域中所有变量,并作为引用主函数体中使用
    • [=] 捕获外部作用域中所有变量,并作为副本在函数体中使用
    • [=,&foo] 按值捕获外部作用域中所有变量,并按引用捕获foo变量
    • [bar] 按值捕获bar变量,同时不捕获其他变量。
    • [this] 捕获当前类中的this指针,让lambda表达式拥有和当前类成员函数同样的访问权限。如果已经使用了&或者=,就默认添加此选项

    例如

    auto f=[](int a){ return a+1; }
    std::cout << f(1)<<std::endl; //输出:2
    可以看到,上面通过一行代码定义了一个小小的功能闭包,用来将输入加1并返回。
    需要注意的是,初始化列表不能用于返回值的自动推导:
    auto x1=[](int i){ return i; }; //OK,return type is int
    auto x2={ return {1,2}; }; //error: 无法推导出返回值类型
    另外,lambda表达式在没有参数列表时,参数列表时可以省略的。因此像下面的写法都是正确的:
    auto f1={ return 1; };
    auto f2=[]{ return 1; }; //省略空参数表

    一个容易出错的细节是关于lambda表达式的延迟调用的:
    int a=0;
    auto f=[=]{ return a; }; //按值捕获外部变量
    a +=1; //a被修改
    std::cout<<f()<<std::endl; //输出0
    虽然通过a +=1,a的值取得了变化,但是因为f中存储的a是按值捕获的,a还是捕获时的值,所以仍然为0

    下面看一下它的具体用法

    class A
    {
    public:
    	int i_=0;
    	
    	void func(int x,int y)
    	{
    		auto x1=[]{ return i_; };                 	//error,没有捕获外部变量
    		auto x2=[=]{ return i_+x+y; };            	//OK,捕获所有外部变量
    		auto x3=[&]{ return i_+x+y; };            	//OK,捕获所有外部变量
    		auto x4=[this]{ return i_+x+y; };         	//OK,捕获this指针
    		auto x5=[this]{ return i_+x+y; };			//error,没有捕获x,y
    		auto x6=[this,x,y]{ return i_+x+y; };		//OK,捕获this指针,x,y
    		auto x7=[this]{ return i_++; };				//OK, 捕获this指针,并修改成员的值		
    	};
    	
    	int a=0,b=1;
    	auto f1=[]{ return a; };        		//error,没有捕获外部变量
    	auto f2=[&]{ return a++; };				//OK,捕获所有外部变量,并对a执行自加运算
    	auto f3=[=]{ return a; };				//OK,捕获所有外部变量,并返回a	
    	auto f4=[=]{ return a++; };				//error,a是以复制方式捕获的,无法修改
    	auto f5=[a]{ return a+b; };				//error,没有捕获变量b
    	auto f6=[a,&b]{ return a+(b++); };		//OK,捕获a和b的引用,并对b做自加运算
    	auto f7=[=,&b]{ return a+(b++); };		//OK,捕获所有变量和b的引用,并对b做自加运算
    }
    
  • 相关阅读:
    CodeBlocks 中fopen函数不支持命令 “r”
    【转载】分享一些Qt学习资源,欢迎下载
    【转载】知乎答案----孙志岗----Google 发布了程序员养成指南,国内互联网巨头是否也有类似的指南和课程推荐
    【转载】谷歌公司推荐的程序员必修课(英文教程)
    【转载】张逸--ThoughtWorks(中国)程序员读书雷达
    在windows环境下,为什么要用Notepad++编辑?
    【转载】池建强--趣谈个人建站
    JAVA入门第二季 第一章 类和对象
    CAP理论总结
    分布式通信方式之消息队列之RocketMQ
  • 原文地址:https://www.cnblogs.com/djcsch2001/p/15397229.html
Copyright © 2020-2023  润新知