首页 > 其他分享 >lambda表达式相关知识

lambda表达式相关知识

时间:2023-04-04 10:00:38浏览次数:42  
标签:闭包 变量 捕获 知识 引用 表达式 lambda

等价于匿名函数对象,又称为“闭包”(closure),更便捷,表达更直接。表达式要素包括:
1:捕获列表
2:参数列表
3:mutable修饰符,表达传值或传引用
4:noexcept
5:返回值类型声明 ->
6:表达式体{...}

lambda表达式可接受参数,可返回值,可模板化,也可以通过传值或传引用从闭包范围内访问变量。
编译器将lambda表达式编译为具名函数对象

对于捕获列表:

lambda表达式,从闭包作用域捕获变量而获得状态,分为传值和传引用。
捕获变量登记与函数对象中的示例数据成员。
 [=] 值捕获所有变量
 [&] 引用捕获所有变量
 [&x] 引用捕获x变量
 [x]  值捕获x
 [=,&x] 默认值捕获,x变量通过引用捕获
 [&,x] 默认引用捕获,x通过值捕获
 [this] 捕获当前对象,可访问所有共有成员,C++20中不允许隐式捕获this
 [=,x],[&,&x] 错误,重复指定
 注意:即便默认要值捕获,全局变量总是使用引用捕获
 使用初始化捕获表达式表达move捕获

示例:

#include <iostream>
#include <vector>
using namespace std;

class Point{
public:
    double x;
    double y;
    void print() const {
        std::cout << x<< ", "<<y<<endl;;
    }
};

int number=100;	//全局变量可以在lambda修改,跨越所有,捕获类型管理不到
int main()
{
	Point p1{100,200};	
    Point p2{100,200};

	//=表示值捕获,就是将外部变量拷贝进来,声明的时候,只能用auto,因为是匿名对象
	//如果没有mutable,会报错,不允许修改p1,p2;如果修改捕获对象,就需要mutable
    auto lambda1 = [=] (int n) mutable	//p1,p2为外部变量,实际调用了拷贝构造函数
	{
		p1.x+=n;	//从外部拷贝进来了,此处修改不影响外部p1
        p1.y+=n;
        p2.x+=n;
        p2.y+=n;
        p1.print();	//print()有个const,如果此时p1,p2没修改(即上面4行不存在),如果print没有const,lambda也需要mutable(编译器认为调用函数也可能更改了)
        p2.print();

        number++;	//全局变量直接使用
	};

    //Lambda_Value lambda1(p1,p2);
    
     lambda1(10);	//外部看不到p1,p2,打印110,210
     lambda1(10);	//多执行一次,会改变lambda对象内部的p1,p2,栈上的lambda对象没有销毁,120,220
     p1.print();	//不改变外部的p1,p2,所以此处打印是一样的,100,200
     p2.print();
     cout<<sizeof(lambda1)<<endl;	//没有捕获,就是一个空类,有捕获后,就有32byte
     cout<<sizeof(Point)<<endl;		//
    
	cout<<"lambda1------------"<<endl;

	auto lambda2 = [&] (int n)	//引用捕获,不用mutable,lambda内部修改会传递到外部
	{
        p1.print();
        p2.print();
		p1.x+=n;
        p1.y+=n;
        p2.x+=n;
        p2.y+=n;

        number++;	//全局的执行也有效果
	};

    //Lambda_Ref lambda2(p1,p2);

    lambda2(100);//p1,p2先打印原始值,之后 p1:200,300; p2:200,300
  
    p1.print();	//200,300
    p2.print();

    p1.x+=5;	//p1.x = 205
    p1.y+=5;	//p1.y = 305
    p2.x+=5;
    p2.y+=5;
    lambda2(100);	//引用捕获,外部更改也会影响引用捕获内部变量,先打印205,305,之后305,405

    //return lambda2;	//隐蔽错误,因为lambda2是引用捕获,函数返回后,p1,p2销毁了,值捕获就没有问题
    cout<<number<<endl;	//lambda内部修改此处表现出来了
    cout<<sizeof(lambda2)<<endl;//只是引用,大小不计算引用参数大小


    cout<<"lambda2------------"<<endl;

    auto lambda3 = [=, &p1] ()	//默认值捕获,但p1使用引用捕获
	{
		p1.x++;
        p1.y++;	//p1修改外部更改,306,406
        p2.print();	//值捕获305,405
	};
	lambda3();
    
	//auto lambda4 = [ &, &p1] () 或者 auto lambda4 = [ =, p1] () 都是重复性错误
     auto lambda4 = [ &, p1] ()	//默认引用捕获,p1是值捕获
	{
        p1.print();	
		p2.x++;	//引用捕获,p2:306,406
        p2.y++;
	};
	lambda4();
    
//	auto lambda5 = [p2, &number] ()	//失败,number不能
	auto lambda5 = [p2] ()	//单独对p2值捕获
	{
        p2.print();	//306,406
	};
	lambda5();
    
    auto lambda6 = [&p1] ()	//单独对p1引用捕获
	{
		p1.x++;
        p1.y++;
	};
    lambda6();
}

 

标签:闭包,变量,捕获,知识,引用,表达式,lambda
From: https://www.cnblogs.com/52ld/p/17285415.html

相关文章

  • SpringBoot外部化配置定时任务cron表达式
    SpringBoot外部化配置定时任务cron表达式背景在日常开发中我们经常会使用到定时任务的情况,SpringBoot为我们很方便的集成了定时任务。我们只需要简单的几部就可以配置好一个定时任务。@ComponentpublicclassLocationTask{@Scheduled(cron="0/10****?")pu......
  • MYSQL基础知识之DQL语句
    1、DQL概念DQL英文全称是DataQueryLanguage(数据查询语言),用来查询数据库中的表的记录2、基本查询语法:#查询全部字段SELECT*FROM表名; #查询多个字段SELECT字段1,字段2,字段3...FROM表名; #去重 语法:SELECTDISTINCT字段列表FROM表名;   3、条......
  • 使用 Lambda Web Adapter 在 Lambda 上 构建 web 应用
    背景介绍AmazonLambda可结合AmazonAPIGateway或ApplicationLoadBalancer,使您无需提前启动或管理服务器即可运行基于restfulAPI的应用程序。此时,Lambda将以JSON格式的字符串接收http事件,并将其转换为对象,它将事件对象以及上下文传递给Lambda函数。而对于已经开......
  • MYSQL基础知识之DDL语句
    一、DDL概念DDL(DataDefinitionLanguage)语言:数据定义语言,用来定义数据库对象,如数据库、数据表和数据字段,主要是进行定义/改变表的结构、数据类型、表之间的链接等操作。常用的语句关键字有CREATE、DROP、ALTER等。 二、数据库操作2.1、linux环境连接数据库语法:mysql-u用......
  • Lambda表达式
    LambdanewThread(()->System.out.println("多线程学习....")).start;/**避免匿名内部类定义过多*可以让你的代码看起来整洁*去掉了一些没有意义代码,只留下核心代码***///lambda简化代码过程publicclassTestLambda{  //1.静态内部类  staticclassLike2implem......
  • (4.3)数组、对象及类数组对象,set的用法,正则表达式的常用方法,蓝桥杯备赛-(生成数组、数
    1.1数组、对象及类数组对象1.数组:​ 数组是有序的数据集合,其中的索引值从0开始递增,并且数组有length属性,可以获取数组内的元素个数,其中的值可以是任何的数组类型。2.对象:​ 对象是无序的是由一个或多个键值对组成的数据集合,对象没有length属性。3.伪数组(类数组对象):​ ......
  • AF,RI,Rep exposure相关知识
    在做Lab2的时候,开始试着去写每个类的Abstractionfunction,Representationinvariant,Safetyfromrepexposure,即抽象函数AF,表示不变量RI和防止表示暴露。但感觉对它们的认知还不是很明确,因此,我将在这详细复习记录下它们都表示什么,记录下对它们的理解。1、AF抽象函数(AF):R......
  • C语言再学习 -- 运算符与表达式
    分三部分来讲一、左值与右值参看:左值与右值首先我们需要理解左值和右值的定义:左值指的是如果一个表达式可以引用到某一个对象,并且这个对象是一块内存空间且可以被检查和存储,那么这个表达式就可以做为一个左值。      右值指的是引用了一个存储在某个内存地址里的数据。从上面......
  • 【功能与技巧】promethues通过记录规则持久化查询,存储rules表达式查询结果为采集指标
    一、查询持续性到目前为止,我们只是在表达式浏览器中运行查询。虽然查看该查询的输出很方便,但结果仍然是临时存储在Prometheus服务器上,我们可以通过以下三种方式使查询持久化: *记录规则:根据查询创建新指标*报警规则:从查询生成警报*可视化:使用Grafana等仪表板可视化查询......
  • git 、 github 相关理论知识
     什么是git:是一个免费、开源的版本控制软件问:什么是版本控制软件答:是一种记录一个或者若干个文件内容变化,以便将来查阅特定版本修订情况的系统 什么是github:是一个网站,该网站可以创建仓库,存放项目代码全球最大 社交编程以及代码托管的网站 设置用户名gitcon......