C++11——lambda表达式

news2024/11/18 17:26:30

在这里插入图片描述

文章目录

    • 1. C++98对自定义类型的排序
    • 2. lambda表达式语法
      • 2.1 捕捉列表
    • 3. lambda底层原理

1. C++98对自定义类型的排序

在C++98中,想要对自定义类型就行排序,我们得自己写仿函数来表明我们相对哪一项进行排序

struct Student
{
	Student(string name, long id, double score)
		:_name(name)
		,_id(id)
		,_score(score)
	{}

	string _name;
	long _id;
	double _score;
};

//按名字排序 -- 降序
struct CmpName
{
	bool operator()(const Student& stu1, const Student& stu2)
	{
		return stu1._name < stu2._name;
	}
};
//按学号排序 -- 降序
struct CmpId
{
	bool operator()(const Student& stu1, const Student& stu2)
	{
		return stu1._id < stu2._id;
	}
};
//按分数排序 -- 降序
struct CmpScore
{
	bool operator()(const Student& stu1, const Student& stu2)
	{
		return stu1._score < stu2._score;
	}
};

int main()
{
	vector<Student> v = { {"张三",101,99.3},{"李四",104,85.2},{"王五",102,99.9} };
	sort(v.begin(), v.end(),CmpName());

	sort(v.begin(), v.end(),CmpId());
	
	sort(v.begin(), v.end(),CmpScore());

	return 0;
}

如果代码风格较好,然后加上了注释,这其他人一看就懂是什么意思。但如果命名不规范,就是个很头疼的问题。

例如:

int main()
{
	vector<Student> v = { {"张三",101,99.3},{"李四",104,85.2},{"王五",102,99.9} };
	sort(v.begin(), v.end(),Cmp1());

	sort(v.begin(), v.end(),Cmp2());
	
	sort(v.begin(), v.end(),Cmp3());

	return 0;
}

这里的仿函数,我们看到就不知道是对哪一项进行排序,就得往前翻,如果前面的命名也不规范,那就十分痛苦。

而且一旦我们的对象的参数多了,那我们就得写出对应的仿函数,这不是很方便,于是在C++11中出现了lambda表达式

2. lambda表达式语法

lambda表达式格式[capture-list] (parameters) mutable -> return-type { statement }

示例:[] (int x,int y)->int { return x+y;}

  • lambda表达式各部分说明

    []:捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来 判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用。

    ():参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以 连同()一起省略。

    mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。

    ->returntype:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略返回值类型明确情况下,也可省略,由编译器对返回类型进行推导

    {statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。

int main()
{
	vector<Student> v = { {"张三",101,99.3},{"李四",104,85.2},{"王五",102,99.9} };
	sort(v.begin(), v.end(), [](const Student& stu1, const Student& stu2)->bool {return stu1._name < stu2._name; });

	sort(v.begin(), v.end(), [](const Student& stu1, const Student& stu2)->bool {return stu1._id < stu2._id; });
	
	sort(v.begin(), v.end(), [](const Student& stu1, const Student& stu2)->bool {return stu1._score < stu2._score; });

	return 0;
}

2.1 捕捉列表

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

    int a = 1;
    int b = 2;
    double rate = 2.5;
    auto f1 = [rate](int x, int y) {return x + y; };
    cout<<f1(a,b)<<endl;	//输出 7.5
    
  • [&var]:表示引用传递捕捉变量var

    适用于对象较大或者需要修改捕捉列表里面的值

    int a = 1;
    int b = 2;
    auto swap1 = [a, b]() mutable {
        //mutable让捕捉的a b可以修改
        //但这里面的a b 属于是外面a b的拷贝
        int tmp = a;
        a = b;
        b = tmp;
    };
    swap1();
    
    
    auto swap2 = [&a, &b] {
        //捕捉引用,可以直接修改外面a b的值了
        int tmp = a;
        a = b;
        b = tmp;
    };
    swap2();
    
  • [=]:表示值传递方式捕获所有父作用域中的变量(包括this)

    捕捉所有的外部变量

    int a = 1;
    int b = 2;
    int c = 3;
    auto f2 = [=]() {
        cout << a << " " << b << " " << c << " " << endl;
    };
    f2();
    
  • [&]:表示引用传递捕捉所有父作用域中的变量(包括this)

    捕捉所有外部变量的引用

    int a = 1;
    int b = 2;
    int c = 3;	
    auto f3 = [&]() {
    cout << ++a << " " << ++b << " " << ++c << " " << endl;
    };
    f3();
    cout << a << " " << b << " " << c << " " << endl;
    //也可以混合捕捉,这里的a就是不可修改的了,普通捕捉
    auto f4 = [&, a] {
    cout << a << " " << ++b << " " << ++c << " " << endl;
    };
    cout << a << " " << b << " " << c << " " << endl;
    
  • [this]:表示值传递方式捕捉当前的this指针

3. lambda底层原理

int main()
{
	auto f1 = [](int x, int y) {return x + y; };
	auto f2 = [](int x, int y) {return x + y; };
	//f1 = f2;	//error
	cout << typeid(f1).name() << endl;
	cout << typeid(f2).name() << endl;
	return 0;
}

这段代码运行之后发现,f1f2的类型是

image-20231018120622477

这里lambda的底层就是一个仿函数,就和范围的for的底层就是迭代器一样,上层将其封装了,调用的就是类的operator()

image-20231018121051482

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1105978.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年电工(中级)证模拟考试题库及电工(中级)理论考试试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年电工&#xff08;中级&#xff09;证模拟考试题库及电工&#xff08;中级&#xff09;理论考试试题是由安全生产模拟考试一点通提供&#xff0c;电工&#xff08;中级&#xff09;证模拟考试题库是根据电工&…

vue3使用swiper6.7.0写轮播图,按钮在轮播图外面

应用场景&#xff1a;需要在header区域&#xff0c;写24小时天气预测轮播&#xff0c;按钮在轮播图外面&#xff0c;默认隐藏左侧按钮&#xff0c;当点击右侧按钮后&#xff0c;左侧按钮显示&#xff0c;当点击到最后一个轮播图的显示时&#xff0c;隐藏右侧按钮。通过获取索引…

使用REPLACE将数据库某一列字段进行字符串操作

REPLACE可以将表里的数据进行替换操作 如&#xff1a;需要把这一列里面的 # 去掉&#xff0c;经过测试&#xff0c;无论是开头、句中还是结尾都可以删除 UPDATE 表名 SET 字段名 REPLACE(字段名 , #, )

解决容器内deepspeed微调大模型报错

解决容器内deepspeed微调大模型报错&#xff1a;[launch.py:315:sigkill_handler] Killing subprocess 问题描述&#xff1a;解决办法 问题描述&#xff1a; 在容器中用deepspeed微调百川大模型2时&#xff0c;出现上述错误&#xff0c;错误是由于生成容器时&#xff0c;共享内…

2023 年值得关注的软件测试趋势(3)

16.云性能工程对业务连续性的影响 检查和改进基于云的应用程序和服务的性能是云性能工程的主要目标&#xff0c;是各种软件测试趋势中云计算的重要组成部分。云提供了无与伦比的可扩展性、灵活性和成本节约&#xff0c;但如果没有适当的性能工程&#xff0c;组织将面临应用程序…

Spark第一课

从数据处理的方式角度: 流式: 一条数据一条数据的处理 微批量: 一小批一小批的处理 批量: 一批数据一批数据的处理(Spark) 从数据处理的延迟角度 离线: 数据处理的延迟是以小时,天为单位 准(近)实时: 以秒为单位 实时:延迟以毫秒为单位, Spark是一个批量数据处理的离线数据分…

微积分(一) 函数的极限

前言 微积分“以直代曲”的思想就是将整体非线性化为局部线性的一个经典的例子&#xff0c;尽管高等数学在定义微分时并没有用到一点线性代数的内容。许多非线性问题的处理――譬如流形、微分几何等&#xff0c;最后往往转化为线性问题。 函数 定义&#xff1a;设 x x x 和 …

京东手机销售数据:2023年9月京东手机行业TOP10品牌排行榜

鲸参谋监测的京东平台9月份手机市场销售数据已出炉&#xff01; 9月份&#xff0c;手机市场销售整体呈现下滑。鲸参谋数据显示&#xff0c;今年9月&#xff0c;京东平台手机销量为300万&#xff0c;环比下降约20%&#xff0c;同比下降约18%&#xff1b;销售额为92亿&#xff0c…

Python 进阶(九):CSV 文件读写(csv模块)

《Python入门核心技术》专栏总目录・点这里 文章目录 1. CSV文件简介2. 导入csv模块3. 读取CSV文件3.1 打开CSV文件3.2 逐行读取数据3.3 获取每行的字段值 4. 写入CSV文件4.1 打开CSV文件4.2 写入数据行 5. 其他操作5.1 指定分隔符5.2 读取和写入字典格式5.3 自定义引号字符 6.…

树的基本操作(数据结构)

树的创建 //结构结点 typedef struct Node {int data;struct Node *leftchild;struct Node *rightchild; }*Bitree,BitNode;//初始化树 void Create(Bitree &T) {int d;printf("输入结点(按0为空结点):");scanf("%d",&d);if(d!0){T (Bitree)ma…

Python学习笔记——存储容器

食用说明&#xff1a;本笔记适用于有一定编程基础的伙伴们。希望有助于各位&#xff01; 列表 列表类似数组&#xff0c;其中可以包含不同类型的元素&#xff0c;写法如下&#xff1a; list1 [Google, Runoob, 1997, 2000] list2 [1, 2, 3, 4, 5 ] list3 ["a", …

Speech | .flac文件转换为.wav文件,并进行重采样(Python脚本)

把flac结尾的&#xff0c;替换为wav文件&#xff0c;然后对wav文件进行重采样&#xff08;48000->22050&#xff09;&#xff0c;可以更换采样率&#xff0c;运行后保存为新的地址&#xff0c;所有文件都在同一文件夹下&#xff08;保证能运行&#xff09;。 # 把flac结尾的…

java中使用sqlserver调用MySQL数据库的表进行操作

项目场景&#xff1a; 部分需求需要对不同的数据库进行操作,我这里是一个小程序里调用了另一个数据 解决方案&#xff1a; 目前我个人使用了两个方案解决的,看自己觉得哪个方便 方案一: 使用JDBC 新建一个实体类,相当于mapper.xml了,然后在这个实体类里进行数据库的连接操作…

2023年中国气体压缩机市场规模及产量分析[图]

气体压缩机是把机械能转换为气体压力能的一种动力装置&#xff0c;常用于风动工具提供气体动力&#xff0c;在石油化工、钻采、冶金等行业也常用于压送氧、氢、氨、天然气、焦炉煤气、惰性气体等介质。常见的气体压缩机包括离心式压缩机、螺杆式压缩机、往复式压缩机等。 气体…

VUE:可收缩工具栏

作者:CSDN @ _乐多_ 本文记录了一个vue可伸缩工具栏组件,代码即插即用。 只需要新增函数名并且填函数体就可以。 效果如下图所示, 文章目录 一、Vue代码一、Vue代码 <template><div class="ToolBar"><div class=

全球范围内先进封装设备划片机市场将迎来新的发展机遇

随着半导体工艺的不断发展&#xff0c;先进封装技术正在迅速发展&#xff0c;封装设备市场也将迎来新的发展机遇。作为先进封装设备中的关键设备之一&#xff0c;划片机的发展也备受关注。 划片机是用于切割晶圆或芯片的设备&#xff0c;其精度和稳定性直接影响到封装产品的质量…

Vue_组件详解

Vue_组件详解 初识组件组件组成组件的根节点父子组件 组件注册全局注册局部注册 组件间数据传递Props&#xff08;父 ----> 子&#xff09;props声明注意问题 组件间数据传递emit&#xff08;子 ----> 父&#xff09; 初识组件 组件&#xff08;Component&#xff09;&a…

WordPress导航主题蘑菇导航源码

蘑菇导航的列表页有两种风格&#xff0c;分别对应宽屏、窄屏。可以点击 文章。博客查看演示。文章页也是如此&#xff0c;这两种风格可以在后台设置。 本站菜单中的 VIP解析、音乐、图床&#xff0c;是单独的源码&#xff0c;不包含在本次主题中。后期看大家的要求&#xff0c…

Python中的循环语句Cycle学习

二、循环语句 1、什么是循环语句 一般编程语言都有循环语句,为什么呢? 那就问一下自己,我们弄程序是为了干什么? 那肯定是为了方便我们工作,优化我们的工作效率啊。 而计算机和人类不同,计算机不怕苦也不怕累,也不需要休息,可以一直做。 你要知道,计算机最擅长就…

【Java】栈和队列的模拟实现(包括循环队列)

异常为空栈异常&#xff1a; public class EmptyStackException extends RuntimeException {public EmptyStackException(){}public EmptyStackException(String msg){super(msg);}}循环队列&#xff1a; class MyCircularQueue {public int[] elem;public int front;//队…