【C++11】lambda表达式详解

news/2024/4/29 12:46:40/文章来源:https://blog.csdn.net/weixin_71138261/article/details/131508817

目录

1.lambda引入

2.语法

3.捕捉列表详解

[ ]  不捕获任何外部变量

[=] 捕获父作用域的所有变量的值,只读不可以修改

[&]捕获父作用域的所有变量的引用,可修改捕获的变量

 [val] 只捕获指定的变量值,不可以修改

[&val] 只捕获外部变量val的引用

[this] 捕获当前类的this指针

 [=,&]混合 

4.mutable


1.lambda引入

在C++98中如想对数据集合中的数据进行排序,需要使用sort函数,该函数默认升序

#include <functional>
#include <algorithm>
int main()
{int arr[] = { 1,2,6,7,4,3,8 };sort(arr, arr + sizeof(arr) / sizeof(arr[0])); for (auto& e : arr)cout << e;cout<<endl;sort(arr, arr + sizeof(arr) / sizeof(arr[0]),greater<int>());for (auto& e : arr)cout << e;return 0;
}

 但如果数据对象是自定义类型就需要用户自己写比较函数

#include <vector>
#include <string>
#include <algorithm>class fruit
{
public:fruit(string name,int price,int num) :_name(name),_price(price),_num(num){}int _price;int _num;string _name;
};struct ComparePriceLess
{bool operator()(const fruit& f1, const fruit& f2){return f1._price < f2._price;}
};struct ComparePriceGreater
{bool operator()(const fruit& f1, const fruit& f2){return f1._price > f2._price;}
};
int main()
{vector<fruit> v = { { "苹果", 2, 5 }, { "香蕉", 3, 4 }, { "橙子", 2,3 }, { "菠萝", 1, 4 } };sort(v.begin(), v.end(), ComparePriceLess());for (auto& e : v)cout<<e._name;return 0;
}

2.语法

但是显然这样的方式每次都要今次那个不同功能的实现,自己手写实在不方便

引入lambda表达式:本质是一个含有operator()的匿名接口(或者类)

lambda的语法:

[capture list] (params list) mutable -> return type { function body }

capture list:捕捉列表,捕获的外部变量列表,可以为空,[ ]开头告诉编译器,现在要用lambda函数

params list:参数列表,与普通函数的形参列表是一样的,如果不需要传递参数,可以连()一起省略

mutable:lambda函数总是一个const函数,但是使用mutable可以取消其常性,使用它的时候,参数列表不能为空,即使参数为空

return type:返回值类型,用追踪返回类型形式声明函数的返回值类型,没有返回值的时候这部分可以省略,返回值类型明确的情况下也可以省略,由编译器对返回值类型推导

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

 

在lambda中参数列表和返回值类型可以省略,但是捕捉列表和函数体是不能省略的,最简单的lambda函数是[ ]{ },该函数不能做任何事情

那么上面的比较函数可以用lambda函数表示成

#include <vector>
#include <string>
#include <algorithm>class fruit
{
public:fruit(string name,int price,int num) :_name(name),_price(price),_num(num){}int _price;int _num;string _name;
};struct ComparePriceLess
{bool operator()(const fruit& f1, const fruit& f2){return f1._price < f2._price;}
};struct ComparePriceGreater
{bool operator()(const fruit& f1, const fruit& f2){return f1._price > f2._price;}
};
int main()
{vector<fruit> v = { { "苹果", 2, 5 }, { "香蕉", 3, 4 }, { "橙子", 2,3 }, { "菠萝", 1, 4 } };sort(v.begin(), v.end(), ComparePriceLess());for (auto& e : v)cout << e._name;cout << endl;sort(v.begin(), v.end(), [](const fruit& f1, const fruit& f2){return f1._price < f2._price;});for (auto& e : v)cout<<e._name;return 0;
}

3.捕捉列表详解

下面所说的父作用域是指包含lambda函数的语句块

在块作用域以外的lambda函数捕捉列表必须为空
在块作用域中的lambda函数仅能捕捉父作用域中局部变量,捕捉任何非此作用域或者非局部变量都会导致编译报错
 

[ ]  不捕获任何外部变量

int main()
{int i = 1;auto func=[](int i) { cout << i << endl; };func(i);return 0;
}

[=] 捕获父作用域的所有变量的值,只读不可以修改

int main()
{int i = 1;auto func=[=]() { cout << i << endl; }; //没有形参 而是直接捕捉ifunc();return 0;
}

[&]捕获父作用域的所有变量的引用,可修改捕获的变量

int main()
{int i = 1;auto func=[&]() { cout << ++i << endl; };func();return 0;
}

 [val] 只捕获指定的变量值,不可以修改


int main()
{int i = 1,j = 2;auto func=[j]() { cout << i << endl; };func();return 0;
}

 报错是因为只捕获了j但是没有捕获i

[&val] 只捕获外部变量val的引用

[this] 捕获当前类的this指针

class fruit
{
public:fruit(int price) :_price(price) {}void Getprice(){cout << _price << endl;}void lambda(){auto func = [this]() {this->Getprice();};func();}
private:int _price;
};int main()
{fruit f(1);f.lambda();
}

 

 [=,&]混合 

一定要用,隔开,不允许重复捕捉比如[=,a] 这样会导致编译错误

int main()
{int i = 1,j = 2;auto func=[=,&j]() { cout << i <<" "<<++j << endl; };func();return 0;
}

综上可以看出lambda相当于一个无名函数,不能直接调用,但是可以用auto推演出类型然后赋给一个函数变量,调用该变量 

此外lambda表达式之间不能相互赋值,即使看起来类型是相同的

4.mutable

mutable关键字说明函数体中可以修改值捕捉的变量,但是不影响外部该变量的值,因为值传递是以拷贝方式实现的

int main()
{int i = 1,j = 2;auto func=[=,&j]()mutable { cout << ++i <<" "<<++j << endl; };func();cout << i << endl;return 0;
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【中间件-Openjob】高性能任务调度框架Openjob简介及快速搭建

介绍基础基础信息任务调度框架对比 特性高可靠高性能定时调度分布式计算延迟任务工作流程权限管理告警监控跨语言 安装访问docker-compose安装在线访问 总结 介绍 一款分布式高性能任务调度框架&#xff0c;支持多种定时任务、延时任务、工作流设计、轻量级分布式计算、无限水平…

谈谈NLP中 大语言模型LLM的 思维链 Chain-of-Thought(CoT)

Chain-of-Thought(CoT) 1.介绍 在过去几年的探索中&#xff0c;业界发现了一个现象&#xff0c;在增大模型参数量和训练数据的同时&#xff0c;在多数任务上&#xff0c;模型的表现会越来越好。因而&#xff0c;现有的大模型LLM&#xff0c;最大参数量已经超过了千亿。 然而…

kong-dashboard安装

简介 kong-dashboard提供了UI界面操作和查看kong&#xff0c;可以进行api、consumers、plugins操作 官网&#xff1a;https://hub.docker.com/r/pgbi/kong-dashboard/ 安装 联网安装 [slviewDEMO:~]$ docker search kong-dashboard INDEX NAME …

【VB6|第19期】vb6通过COM组件操作Excel

日期&#xff1a;2023年7月3日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xff…

【elementplus】解决el-table开启show-overflow-tooltip后,tooltip的显示会被表格边框遮挡的问题

如图所示&#xff1a; 原因&#xff1a; 1. el-table没有设置高度&#xff1b;2.就是被遮住了 解决&#xff1a; 方法一&#xff1a;给el-table设置高度 方法二: .el-table {overflow: visible !important;}如果不想给el-table设置高度&#xff0c;就直接使用方法二解决即可

MyBatisPlus基础知识

一、MyBatisPlus 1.MyBatisPlus入门案例与简介 这一节我们来学习下MyBatisPlus的入门案例与简介&#xff0c;这个和其他课程都不太一样&#xff0c;其他的课程都是先介绍概念&#xff0c;然后再写入门案例。而对于MyBatisPlus的学习&#xff0c;我们将顺序做了调整&#xff0…

初级保育员专业知识生活管理考试题库及答案

​本题库是根据最新考试大纲要求&#xff0c;结合近年来考试真题的重难点进行汇编整理组成的全真模拟试题&#xff0c;考生们可以进行专项训练&#xff0c;查漏补缺巩固知识点。本题库对热点考题和重难点题目都进行了仔细的整理和编辑&#xff0c;相信考生在经过了针对性的刷题…

JAVA开发( 腾讯云消息队列 RocketMQ使用总结 )

一、问题背景 之所以需要不停的总结是因为在java开发过程中使用到中间件实在太多了&#xff0c;久久不用就会慢慢变得生疏&#xff0c;有时候一个中间很久没使用&#xff0c;可能经过了很多版本的迭代&#xff0c;使用起来又有区别。所以还是得不断总结更新。最近博主就是在使用…

jenkins的环境搭建

jenkins 环境 安装 我之前使用war安装、安装比较简单、就是jenkins的 对应的插件不能下载下来、后来发现是版本的问题、使用docker-compose 安装、jenkins安装 插件很容易安装下来 1、安装jdk 解压jdk 配置环境变量 #set java environment JAVA_HOME/usr/local/jdk1.8.0_281…

blender 之点云渲染(论文渲图)

blender 之点云渲染&#xff08;论文渲图&#xff09; 一、导入点云1.新建2.导入点云3.位置移动&放大缩小 二、Geometry Nodes实体化点云1.新建节点2.实体化 三、给实体化点云添加材质四、设置渲染引擎更换为Cycles。 五、对准视角1.新建一个球2.创建相机视角跟踪3.将uv球挪…

二、Spring Cloud Eureka 简介、快速入门

注册发现中心 Eureka 来源于古希腊词汇&#xff0c;意为“发现了”。在软件领域&#xff0c; Eureka 是 Netflix 在线影片公司开源的一个服务注册与发现的组件&#xff0c;和其他 Netflix 公司的服务组件&#xff08;例如负载均衡、熔断器、网关等&#xff09; 一起&#xff0…

LLM prompt提示构造案例

参考&#xff1a; https://github.com/PlexPt/awesome-chatgpt-prompts-zh 吴恩达 prompt工程应用&#xff1a; https://www.bilibili.com/video/BV1No4y1t7Zn prompt构造案例代码 prompt """文本分类任务&#xff1a;将一段用户给外卖服务的评论进行分类…

初级保育员专业知识配合教育考试题库及答案

本题库是根据最新考试大纲要求&#xff0c;结合近年来考试真题的重难点进行汇编整理组成的全真模拟试题&#xff0c;考生们可以进行专项训练&#xff0c;查漏补缺巩固知识点。本题库对热点考题和重难点题目都进行了仔细的整理和编辑&#xff0c;相信考生在经过了针对性的刷题练…

Linux基础笔记

已经有很长很长一段时间没有更新帖子了&#xff0c;一眨眼2023 已经过半&#xff0c;这些日子里&#xff0c;有太多太多事情要做了&#xff0c;今年只更新了几篇&#xff0c;这几天刚好有空&#xff0c;浅浅更新一篇叭&#xff01;~~~ 首先&#xff0c;Linux是一种开源的操作系…

手搓GPT系列之 - 通过理解LSTM的反向传播过程,理解LSTM解决梯度消失的原理 - 逐条解释LSTM创始论文全部推导公式,配超多图帮助理解(下篇)

本文承接上篇上篇在此和中篇中篇在此&#xff0c;继续就Sepp Hochreiter 1997年的开山大作 Long Short-term Memory 中APPENDIX A.1和A.2所载的数学推导过程进行详细解读。希望可以帮助大家理解了这个推导过程&#xff0c;进而能顺利理解为什么那几个门的设置可以解决RNN里的梯…

git push origin masterEverything up-to-date解决方法

按住这个看一下很简单的问题&#xff0c;我在网上看了很多就是没找到能用的&#xff0c;最后找到了这个看起来写的很简单的一个文章&#xff0c;但他写的真的有用。 出现的问题 解决步骤第一步 git add . 第二步 git commit -m “message” 第三步 git push origin master…

PyTorch示例——ResNet34模型和Fruits图像数据

PyTorch示例——ResNet34模型和Fruits图像数据 前言导包数据探索查看数据集构建构建模型 ResNet34模型训练绘制训练曲线 前言 ResNet34模型&#xff0c;做图像分类数据使用水果图片数据集&#xff0c;下载见Kaggle Fruits Dataset (Images)Kaggle的Notebook示例见 PyTorch——…

综合实验---基于卷积神经网络的目标分类案例

文章目录 配置环境猫狗数据分类建模猫狗分类的实例基准模型猫狗分类的实例基准模型之数据增强问题回答 配置环境 ①首先打开 cmd&#xff0c;创建虚拟环境。 conda create -n tf1 python3.6如果报错&#xff1a;‘conda’ 不是内部或外部命令,也不是可运行的程序 或批处理文件…

[github-100天机器学习]day1 data preprocessing

https://github.com/LiuChuang0059/100days-ML-code/blob/master/Day1_Data_preprocessing/README.md#step-6-feature-scaling—特征缩放 数据预处理 数据帧(Data Frame) 二维的表格形式&#xff0c;类似于电子表格或关系型数据库中的表。数据帧通常被用来存储和操作结构化数据…

科技项目验收测试报告有什么注意事项和疑惑?

科技项目验收测试报告是一份重要的文件&#xff0c;用于评估科技项目的质量和可靠性&#xff0c;对项目的成功交付具有关键作用。在项目完成的最后阶段&#xff0c;通过对项目进行全面测试和评估&#xff0c;以确保项目符合预期的目标和需求&#xff0c;并满足用户的期望。 一…