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(); //调用func2
	std::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(); //调用func1
	std::cout << " func1: " << a << " - " << b << std::endl;

	auto func2 = [&a, &b]()mutable->int {
		++a;
		++b;
		return a + b;
		};
	func2(); //调用func2
	std::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表达式。

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

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

相关文章

消息开始事件message start event

一&#xff1a;bpmn 二&#xff1a;java repositoryService.createDeployment().name("消息事件流程").addClasspathResource("bpmn/msg_event_process.bpmn").deploy(); identityService.setAuthenticatedUserId("huihui"); ProcessInstance p…

vue3中ref和reactive联系与区别以及如何选择

vue3中ref和reactive区别与联系 区别 1、ref既可定义基本数据类型&#xff0c;也可以定义引用数据类型&#xff0c;reactive只能定义应用数据类型 2、ref在js中取响应值需要使用 .value&#xff0c;而reactive则直接取用既可 3、ref定义的对象通过.value重新分配新对象时依旧…

放电深度对电池寿命的影响

一、SOC和DOD概念 SOC&#xff1a;State Of Charge. 电池SOC是指荷电状态&#xff0c;是用来反映电池的剩余容量的&#xff0c;其数值上定义为剩余容量占电池容量的比值&#xff0c;常用百分数表示&#xff1b;其取值范围为0~1&#xff0c;当“SOC0”时表示电池放电完全&#…

python爬虫实战(6)--获取某度热榜

1. 项目描述 需要用到的类库 pip install requests pip install beautifulsoup4 pip install pandas pip install openpyxl然后&#xff0c;我们来编写python脚本&#xff0c;并引入需要的库&#xff1a; import requests from bs4 import BeautifulSoup import pandas as p…

SpringBoot 自动装配原理

一、什么是自动装配 自动装配是指应用程序启动时由容器自动扫描和装配相关的组件和模块&#xff0c;无须像传统的spring那样在xml文件中手动配置Bean&#xff0c;从而简化了应用程序的配置过程&#xff0c;提高开发效率。 二、SpringBootApplication解析 进入到这个 SpringB…

概率中的 50 个具有挑战性的问题 [9/50]:掷骰子

一、说明 我最近对与概率有关的问题产生了兴趣。我偶然读到了弗雷德里克莫斯特勒&#xff08;Frederick Mosteller&#xff09;的《概率论中的五十个具有挑战性的问题与解决方案》&#xff09;一书。我认为创建一个系列来讨论这些可能作为面试问题出现的迷人问题会很有趣。每篇…

你需要尽早知道的15个开源网络安全工具

在本文中&#xff0c;你将找到一个开放源码网络安全工具列表&#xff0c;你一定要查看这些工具。 开源工具代表了技术版图中的一股有活力的力量&#xff0c;体现了创新、协作和可访问性&#xff0c;这些工具是根据透明度和社区驱动的原则开发的&#xff0c;使用户能够根据其独特…

Vue-13、Vue深度监视

1、监视多级结构中某个属性的变化 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>watch深度监视</title><script type"text/javascript" src"https://cdn.jsdelivr.net/npm…

Vue基础-搭建Vue运行环境

这篇文章介绍了在Vue.js项目中进行开发环境搭建的关键步骤。包括node.js安装和配置、安装Vue及Vue CLI工具、安装webpack模板、安装vue-router、创建Vue项目等步骤。这篇文章为读者提供了清晰的指南&#xff0c;帮助他们快速搭建Vue.js开发环境&#xff0c;为后续的项目开发奠定…

端到端自动驾驶

自动驾驶主要流程&#xff1a;感知->预测->规划 预测是预测周围目标&#xff08;车、行人、动物等&#xff09;的轨迹&#xff0c;规划是规划自车的运动轨迹。 UniAD[CVPR 2023]: 使用transformer架构&#xff0c;统一自动驾驶流程&#xff0c;完成所有检测&#xff0c…

如何上传苹果ipa安装包?

目录 引言 摘要 第二步&#xff1a;打开appuploader工具 第二步&#xff1a;打开appuploader工具&#xff0c;第二步&#xff1a;打开appuploader工具 第五步&#xff1a;交付应用程序&#xff0c;在iTunes Connect中查看应用程序 总结 引言 在将应用程序上架到苹果应用…

Navicat 技术干货 | 为 MySQL 表选择合适的存储引擎

MySQL 是最受欢迎的关系型数据库管理系统之一&#xff0c;提供了不同的存储引擎&#xff0c;每种存储引擎都旨在满足特定的需求和用例。在优化数据库和确保数据完整性方面&#xff0c;选择合适的存储引擎是至关重要的。今天&#xff0c;我们将探讨为 MySQL 表选择合适的存储引擎…

【开源项目】轻量元数据管理解决方案——Marquez

大家好&#xff0c;我是独孤风。 又到了本周的开源项目推荐。最近推荐的元数据管理项目很多&#xff0c;但是很多元数据管理平台的功能复杂难用。 那么有没有轻量一点的元数据管理项目呢&#xff1f; 今天为大家推荐的开源项目&#xff0c;就是一个轻量级的元数据管理工具。虽然…

《SPSS统计学基础与实证研究应用精解》视频讲解:SPSS的功能特色

《SPSS统计学基础与实证研究应用精解》1.2 SPSS的功能特色 视频为《SPSS统计学基础与实证研究应用精解》张甜 杨维忠著 清华大学出版社 一书的随书赠送视频讲解1.2节内容。本书已正式出版上市&#xff0c;当当、京东、淘宝等平台热销中&#xff0c;搜索书名即可。本书旨在手把手…

NSSCTF Interesting_include

开启环境: 通过审计,我们可知: flag在flag.php中,可以利用php中伪协议 payload:?filterphp://filter/readconvert.base64-encode/resourceflag.php 将其base64解码就是flag. NSSCTF{3dc54721-be9e-444c-8228-7133fba76ad4}

回归预测 | Matlab基于CPO-BP基于冠豪猪算法优化BP神经网络的数据多输入单输出回归预测

回归预测 | Matlab基于CPO-BP基于冠豪猪算法优化BP神经网络的数据多输入单输出回归预测 目录 回归预测 | Matlab基于CPO-BP基于冠豪猪算法优化BP神经网络的数据多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CPO-BP回归基于冠豪猪优化算法[24年新…

关于Vue前端接口对接的思考

关于Vue前端接口对接的思考 目录概述需求&#xff1a; 设计思路实现思路分析1.vue 组件分类和获取数值的方式2.http 通信方式 分类 如何对接3.vue 组件分类和赋值方式&#xff0c; 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your p…

力扣最热一百题——只出现一次的数字

这个合集已经很久没有更新了&#xff0c;今天来更新更新~~~ 目录 力扣题号 题目 题目描述 示例 提示 题解 Java解法一&#xff1a;Map集合 Java解法二&#xff1a;位运算 C位运算代码 力扣题号 136. 只出现一次的数字 - 力扣&#xff08;LeetCode&#xff09; 下述题…

腾讯云对象存储COS计算文件的大小

properties配置类 TencentCos.APPIDxxxxx TencentCos.SecretIdxxxxxxx TencentCos.SecretKeyxxxxxx TencentCos.testBucketxxxxxx TencentCos.CosPathhttps://xxxxxxxx.cos.ap-chengdu.myqcloud.com TencentCos.regionap-chengdu读取properties中的配置 import lombok.AllArg…

Thingsbaord采用redis缓存(自用)

在CentOS系统上&#xff0c;您可以通过以下步骤使用yum安装Redis&#xff1a; 添加EPEL仓库&#xff1a; 首先&#xff0c;需要添加EPEL&#xff08;Extra Packages for Enterprise Linux&#xff09;仓库&#xff0c;因为Redis可能不在默认的CentOS仓库中。使用以下命令添加EP…