C++11_lambda表达式

文章目录

  • 一、lambda表达式
    • 1.lambda的组成
      • 2.[capture-list] 的其他使用方法
      • 2.1混合捕捉
  • 二、lambda表达式的使用场景
    • 1.替代仿函数
  • 总结


一、lambda表达式

lambda表达式是C++11新引入的功能,它的用法与我们之前学过的C++语法有些不同。

1.lambda的组成

[capture-list] (parameters) mutable -> return-type { statement }

[capture-list] : 捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来
判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda
函数使用。
(parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以
连同()一起省略
mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量
性。使用该修饰符时,参数列表不可省略(即使参数为空)。
->returntype:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推
导。
{statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量

示例代码如下

	int a = 2;int b = 3;auto func1 = [](int a, int b)->int {return a + b;};std::cout << func1(a, b) << std::endl;

首先看示例代码
“[capture-list]”: 下面再讲,这里需要记住是[]即便里面没有内容也不可以省略。
“(parameters)” :很像我们函数的参数列表,而实际上在这里的作用也是如此。如果没有参数,那么可以连同()一起省略
“->returntype” :->返回值类型,一般都可以省略,但是推荐不省略。
“{}”: 可以理解为函数体,内部写自己想实现的功能。


示例代码如下

	int a = 2;int b = 3;auto func1 = [a, b]()->int {++a;  编译报错++b;  编译报错return a + b;};auto func2 = [a, b]()mutable->int {++a;   运行通过++b;return a + b;};func2(); //调用func2std::cout << " func2: " << a << " - " << b << std::endl;

“[capture-list]”: 捕捉的是现有变量让它们能在函数体内运行。
func1 和 func2 唯一的区别就是有没有加mutable(可变的)。默认情况下,lambda函数总是一个const函数,mutable可以取消其常量
性。 所以func2使用mutable就可以改变函数体内a和b的值。

那么这里提出疑问,外面的a和b的值是否被修改? -> 不会
在这里插入图片描述

因为这里其实是一个传值拷贝,如果你需要在lambda内部改变外面的a,b,可以使用引用

	int a = 2;int b = 3;auto func1 = [a, b]()mutable->int {++a;++b;return a + b;};func1(); //调用func1std::cout << " func1: " << a << " - " << b << std::endl;auto func2 = [&a, &b]()mutable->int {++a;++b;return a + b;};func2(); //调用func2std::cout << " func2: " << a << " - " << b << std::endl;

在这里插入图片描述

2.[capture-list] 的其他使用方法

“[=]”:根据上下文全部以值传递捕捉变量
"[&]':根据上下文全部以引用传递捕捉变量

	int a = 1;int b = 2;double d = 2.2;std::string str = "hello world";auto func1 = [=]()mutable {  //根据上下文全部以值传递捕捉变量std::cout << a << " " << b << " " << d << " " << str << std::endl;a = 10;};func1();std::cout << "a: " << a << std::endl << std::endl;;auto func2 = [&]()mutable {  //根据上下文全部以引用传递捕捉变量std::cout << a << " " << b << " " << d << " " << str << std::endl;a = 10;};func2();std::cout << "a: " << a << std::endl;

在这里插入图片描述


2.1混合捕捉

	int a = 1;int b = 2;double d = 2.2;std::string str = "hello world";auto func1 = [= , &a]()mutable{//除a以引用传递捕捉,其他根据上下文全部以值传递捕捉变量std::cout << a << " " << b << " " << d << " " << str << std::endl;a = 10;};func1();std::cout << "a: " << a << std::endl << std::endl;;auto func2 = [&, a]()mutable{//除a以值传递捕捉,其他根据上下文全部以引用传递捕捉变量std::cout << a << " " << b << " " << d << " " << str << std::endl;a = 1;};func2();std::cout << "a: " << a << std::endl;

在这里插入图片描述

二、lambda表达式的使用场景

1.替代仿函数

仿函数我们之前对于实现很多STL中的容器的排序都使用过,应该不陌生,而lambda表达式我们看来其实也跟一个函数差不多,一样有参数,一样有返回值,一样能写函数体,所以我们就可以使用lambda来取代仿函数

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<functional>
struct Goods {Goods(std::string name, double price, size_t evaluation):_name(name),_price(price),_evaluation(evaluation) {}std::string _name;double _price;size_t _evaluation;
};int main()
{std::vector<Goods> v = {{ "苹果", 2.1, 5 },{ "香蕉", 3, 4 }, { "橙子", 2.2, 3 },{ "菠萝",1.5,4 }};std::sort(v.begin(), v.end(), [](const Goods& s1, const Goods& s2)->bool {return s1._name < s2._name;}); // 字符串升序for (auto& a : v){std::cout << a._name << " - " << a._price << " - " << 	a._evaluation << std::endl;}std::cout << std::endl;std::sort(v.begin(), v.end(), [](const Goods& s1, const Goods& s2)->bool {return s1._name > s2._name;}); // 字符串降序for (auto& a : v){std::cout << a._name << " - " << a._price << " - " << a._evaluation << std::endl;}std::cout << std::endl;std::sort(v.begin(), v.end(), [](const Goods& s1, const Goods& s2)->bool {return s1._price < s2._price;}); // 价格升序for (auto& a : v){std::cout << a._name << " - " << a._price << " - " << a._evaluation << std::endl;}std::cout << std::endl;std::sort(v.begin(), v.end(), [](const Goods& s1, const Goods& s2)->bool {return s1._evaluation < s2._evaluation;}); // 评价升序for (auto& a : v){std::cout << a._name << " - " << a._price << " - " << a._evaluation << std::endl;}std::cout << std::endl;return 0;
}

在这里插入图片描述

总结

这些就是lambda表达式的全部内容,lambda表达式还是十分有用的,对于一些我们只需要运行一遍的函数或者是对象内传仿函数类型,我们都可以使用使用lambda表达式。

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

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

相关文章

【Java万花筒】解锁Java并发之门:深入理解多线程

Java并发编程艺术&#xff1a;深度剖析多线程利器 前言 在当今软件开发的世界中&#xff0c;多线程编程已经变得愈发重要。面对多核处理器的普及和复杂的系统架构&#xff0c;开发人员需要深入了解并发编程的原理和实践&#xff0c;以充分发挥硬件的性能潜力。本文将带您深入…

【C++进阶05】AVL树的介绍及模拟实现

一、AVL树的概念 二叉搜索树的缺点 二叉搜索树虽可以缩短查找效率 但如果数据有序或接近有序 二叉搜索树将退化为单支树 查找元素相当于在顺序表中搜索元素&#xff0c;效率低下 AVL树便是解决此问题 向二叉搜索树中插入新结点 并保证每个结点的左右子树 高度之差的绝对值不超…

新能源汽车的三电指的是什么,作用有什么区别。

问题描述&#xff1a;新能源汽车的三电指的是什么&#xff0c;作用有什么区别。 问题解答&#xff1a; "新能源汽车的三电"通常指的是新能源汽车中的三大核心电气系统&#xff0c;包括&#xff1a;高压电池系统、电动机驱动系统和电子控制系统。这三者协同工作&…

Java诊断利器Arthas

https://arthas.aliyun.com/doc/https://arthas.aliyun.com/doc/ 原理 利用java.lang.instrument(容器类) 做动态 Instrumentation(执行容器) 是 JDK5 的新特性。使用 Instrumentation&#xff0c;开发者可以构建一个独立于应用程序的代理程序&#xff08;Agent&#xff09;&…

汽车IVI中控开发入门及进阶(十二):手机投屏

前言: 汽车座舱有车载中控大屏、仪表/HUD多屏的显示能力,有麦克风/喇叭等车载环境更好的音频输入输出能力,有方控按键、旋钮等方便的反向控制输入能力,还有高精度的车辆数据等。但汽车座舱中控主机硬件计算能力升级迭代周期相对较长,汽车的应用和服务不够丰富。现在很多汽…

.NetCore部署微服务(二)

目录 前言 概念 一 Consul注册服务中心 1.1 consul下载 1.2 consul运行 二 服务注册 2.1 安装Consul包 2.2 修改配置文件 2.3 注入Consul服务 2.3 修改Controller&#xff0c;增加HealthCheck方法 三 运行服务 3.1 docker运行服务 前言 上一篇讲到微服务要灵活伸缩…

「超级细菌」魔咒或将打破,MIT 利用深度学习发现新型抗生素

作者&#xff1a;加零 编辑&#xff1a;李宝珠、三羊 MIT 利用图神经网络 Chemprop 识别潜在抗生素&#xff0c;特异性杀死鲍曼不动杆菌。 自然界中充满了各种各样的微生物&#xff0c;例如结核杆菌&#xff08;导致肺结核&#xff09;、霍乱弧菌&#xff08;导致霍乱&#…

数据结构实验4:链表的基本操作

目录 一、实验目的 二、实验原理 1. 节点 2. 指针 3.链表的类型 3.1 单向链表 3.2 双向链表 3.3 单向循环链表 3.4 双向循环链表 4. 单链表的插入 4.1 头插法 4.2 尾插法 4.3 在指定位置插入元素 5. 单链表的删除 5.1 删除指定数值的节点 5.2 删除指定位置的节点 …

Pytorch从零开始实战16

Pytorch从零开始实战——ResNeXt-50算法的思考 本系列来源于365天深度学习训练营 原作者K同学 对于上次ResNeXt-50算法&#xff0c;我们同样有基于TensorFlow的实现。具体代码如下。 引入头文件 import numpy as np from tensorflow.keras.preprocessing.image import Ima…

Rust基础类型之布尔类型和字符

布尔类型 Rust 中的布尔类型为 bool&#xff0c;仅仅有两个值&#xff0c;true 和 false。比如下方代码&#xff1a; let flag1 true; let flag2: bool false;字符 Rust 中的字符类型是 char&#xff0c;值用单引号括起来。 fn main() {let char1 z;let char2: char ℤ…

TensorRt(5)动态尺寸输入的分割模型测试

文章目录 1、固定输入尺寸逻辑2、动态输入尺寸2.1、模型导出2.2、推理测试2.3、显存分配问题2.4、完整代码 这里主要说明使用TensorRT进行加载编译优化后的模型engine进行推理测试&#xff0c;与前面进行目标识别、目标分类的模型的网络输入是固定大小不同&#xff0c;导致输入…

Java单元测试 1.SpringBoot 2.普通java工程

1)SpringBoot工程 1.注意&#xff1a;新建SpringBoot工程时&#xff0c;一定要根据你当前的jdk版本选择好SpringBoot的版本&#xff0c;比如&#xff1a;jdk为11&#xff0c;则不能创建3.x的SpringBoot工程&#xff0c;有时候2021版本的idea强制我创建3.x版本的SpringBoot&…

【打卡】牛客网:BM79 打家劫舍(二)

资料&#xff1a; dp.clear()会把dp的size变为0。 assign和insert的对比&#xff1a; v1.assign(v2.begin(), v2.end()); v1.insert(pos,n,elem); //在pos位置插入n个elem数据&#xff0c;无返回值。 v1.insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据&#xff0…

【现代密码学】笔记3.4-3.7--构造安全加密方案、CPA安全、CCA安全 《introduction to modern cryphtography》

【现代密码学】笔记3.4-3.7--构造安全加密方案、CPA安全、CCA安全 《introduction to modern cryphtography》 写在最前面私钥加密与伪随机性 第二部分流加密与CPA多重加密 CPA安全加密方案CPA安全实验、预言机访问&#xff08;oracle access&#xff09; 操作模式伪随机函数PR…

Java微服务系列之 ShardingSphere - ShardingSphere-JDBC

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 系列专栏目录 [Java项…

复习python从入门到实践——类

复习python从入门到实践——类 学好继承&#xff0c;你就初步学习了程序面向对象啦&#xff5e;本章我依旧为大家整理好了运行的步骤&#xff0c;以及举了尽可能清晰简单的例子为大家展示。 目录 复习python从入门到实践——类1. Syntax注意&#xff1a; 2.修改属性值3.继承4…

报错解决:No module named ‘pytorch_lightning‘ 安装pytorch_lightning

报错记录 执行如下代码&#xff1a; import pytorch_lightning报错&#xff1a; No module named ‘pytorch_lightning’ 解决方式 安装pytorch_lightning包即可。 一般情况下&#xff0c;缺失的包通过pip安装&#xff0c;即&#xff1a; pip install pytorch_lightning然…

C++性能优化简单总结

什么样的代码是高度优化的&#xff1f; 我们先出去数据结构和算法本身的使用。C 的高效代码通常是利用了各种编译器优化和语言特性来最大程度地提高执行效率和资源利用率的代码。我们需要编写编译器友好的代码来让编译器优化或者说编写出不用编译器高度优化优化也能达到同样效果…

1 快速前端开发

1 前端开发 目的&#xff1a;开发一个平台&#xff08;网站&#xff09;- 前端开发&#xff1a;HTML、CSS、JavaScript- Web框架&#xff1a;接收请求并处理- MySQL数据库&#xff1a;存储数据地方快速上手&#xff1a;基于Flask Web框架让你快速搭建一个网站出来。1.快速开发…

HarmonyOS应用开发学习笔记 应用上下文Context 获取文件夹路径

1、 HarmoryOS Ability页面的生命周期 2、 Component自定义组件 3、HarmonyOS 应用开发学习笔记 ets组件生命周期 4、HarmonyOS 应用开发学习笔记 ets组件样式定义 Styles装饰器&#xff1a;定义组件重用样式 Extend装饰器&#xff1a;定义扩展组件样式 5、HarmonyOS 应用开发…