当前位置: 首页 > news >正文

C++笔记之lambda表达式

在这里插入图片描述

引言

Lambda表达式是从C++ 11版本引入的特性,利用它可以很方便的定义匿名函数对象,通常作为回调函数来使用。大家会经常拿它和函数指针,函数符放在一起比较,很多场合下,它们三者都可以替换着用。

语法

[ captures ] ( params ) specs requires (optional) {body}

上面是完整的Lambda表达式结构,从左到右分别是:

  • capture–捕获列表
  • params–参数列表
  • specification列表-- 可选部分,这块部分主要由变量说明符、异常、返回类型等组成
  • requires – C++20 版本开始增加的
  • body-- 函数体

关于specification和requires部分的详细描述可以参考:https://en.cppreference.com/w/cpp/language/lambda

我们平时的开发工作可能不会基于C++20版本,一般都是C++17及以下,所以就先记录一下,平时开发所接触的Lambda表达式。哪些新版本增加的相关特性就暂不讨论。

常见的Lambda表达式语法:

图片引自 微软C++课程

结构描述:

  1. 捕获列表,可以捕获外部变量
  2. 形参列表 (可选)
  3. 变量说明符(可选)属于specification列表,用来表示可以修改值捕获的变量,后面会详细说明
  4. exception (可选)属于specification列表,用来表示是否会有异常
  5. 返回类型 (可选)
  6. 函数体

从上面的结构描述,我们能看到,最简洁的lambda表达式应该是这样:

[]{}

我们常用的lambda表达式有以下几种:

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

捕获列表

lambda表达式有两种捕获其作用域外部变量的方式,一种是值捕获,一种是引用捕获。

值捕获
#include <iostream>
using namespace std;
int main(int argc, char **argv) {int a = 100;auto test = [a]() mutable {a++;cout << "inside, a:" << a << endl;};test();cout << "outsize, a:" << a << endl;return 0;
}

输出结果:

inside, a:101
outsize, a:100

值捕获的情况下,如果需要某个特地的外部变量,那么直接在捕获列表里面写相应的变量名即可,如果想要值捕获所以外部变量,可使用如下形式:

[=]

上面的例子中有mutable,这个关键字的作用是运行lambda内部可以修改值捕获的变量,默认情况下,值捕获的变量是只读的。

引用捕获
#include <iostream>
using namespace std;
int main(int argc, char **argv) {int a = 100;auto test = [&a]() {a++;cout << "inside, a:" << a << endl;};test();cout << "outsize, a:" << a << endl;return 0;
}

输出结果:

inside, a:101
outsize, a:101

引用捕获外部变量的话,需要在变量名前加上**&,如果想要以引用捕获的方式访问所以外部变量,可以使用:[&]**

注意,这里我们移除了mutable关键字。

值捕获&引用捕获

因为是捕获列表嘛,所以当然可以互相组合搭配了,不然怎么能达到列表的定义呢。例如,我们想要以值捕获的方式捕获factor变量,以引用捕获的方式捕获total变量,那么可以用如下的方式:

[&total, factor]
[factor, &total]
[&, factor]
[=, &total]

以上面第一个方式举个例子:

#include <iostream>
using namespace std;
int main(int argc, char **argv) {int total = 100;float factor = 0.2f;auto test = [&total, factor]() mutable {factor = 0.5f;total = static_cast<int>(total * factor);cout << "inside, total:" << total << ", factor:" << factor << endl;};test();cout << "outsize, total:" << total << ",factor:" << factor << endl;return 0;
}

输出结果:

inside, total:50, factor:0.5
outsize, total:50,factor:0.2

在两种捕获方式互相搭配的使用过程中,需要注意一点的是,当捕获列表中已经使用了**&来捕获所以外部变量,就不能再使用&变量名**,捕获指定变量了,同理,值捕获也是这样。例如:

struct S { void f(int i); };void S::f(int i) {[&, i]{};      // OK[&, &i]{};     // ERROR: i preceded by & when & is the default[=, this]{};   // ERROR: this when = is the default[=, *this]{ }; // OK: captures this by value. See below.[i, i]{};      // ERROR: i repeated
}
注意

上面的例子中,访问外部的变量,都必须通过捕获列表“处理”一下,内部才能访问,其实还有一些情况是不需要捕获,lambda就能访问的。例如:

  • 当lambda要访问的变量是全局的或者静态(static)的,可以直接使用
  • Thread Local 变量
  • constant expression 并且没有mutable成员 (只读)
  • const修饰的non-volatile int型字面量 或者 由constant expression初始化的枚举类型 (只读)

下面举一些例子:

#include <iostream>
using namespace std;
int total = 100;
int main(int argc, char **argv) {static float factor = 0.2f;auto test = []() {factor = 0.5f;total = static_cast<int>(total * factor);cout << "inside,global total:" << total << ", static factor:" << factor<< endl;};test();cout << "outsize,global total:" << total << ", static factor:" << factor<< endl;return 0;
}

输出结果:

inside,global total:50, static factor:0.5
outsize,global total:50, static factor:0.5
#include <iostream>
#include <thread>
using namespace std;
int main(int argc, char **argv) {const int x = 1024;enum TYPE { kTypeApp = 0, kTypeUser };auto test = []() {cout << "type:" << kTypeUser << endl;cout << "x:" << x << endl;};test();return 0;
}

输出结果:

type:1
x:1024

参数列表&返回类型

lambda除了通过捕获列表的方式访问外部变量,也可以通过传递参数来与外界交流。跟普通函数没啥区别,这个没啥好说的。需要知道的是lambda支持它的参数也可以是lambda表示式。

返回类型跟普通函数差别也不大,同样需要注意的是,跟参数列表一样,也是支持返回lambda表达式的。同时,如果不指定返回类型的话,那么可以用auto关键字接收返回结果,自动推导结果。

#include <functional>
#include <iostream>
using namespace std;
int main() {auto addtwointegers = [](int x) -> function<int(int)> {return [=](int y) { return x + y; };};auto higherorder = [](const function<int(int)>& f, int z) {return f(z) * 2;};auto answer = higherorder(addtwointegers(7), 8);cout << answer << endl;
}

输出结果:

30

lambda嵌套

lambda表达式内部还可以创建lambda表达式,套娃的感觉🪆。

#include <iostream>
using namespace std;
int main()
{int ret = [](int x) { return [](int y) { return y * 2; }(x) + 3; }(5);cout << ret << endl;
}

输出结果:

13

参考

https://learn.microsoft.com/en-us/cpp/cpp/examples-of-lambda-expressions?view=msvc-170

https://en.cppreference.com/w/cpp/language/lambda

相关文章:

C++笔记之lambda表达式

引言 Lambda表达式是从C 11版本引入的特性&#xff0c;利用它可以很方便的定义匿名函数对象&#xff0c;通常作为回调函数来使用。大家会经常拿它和函数指针&#xff0c;函数符放在一起比较&#xff0c;很多场合下&#xff0c;它们三者都可以替换着用。 语法 [ captures ] (…...

flink大数据处理流式计算详解

flink大数据处理 文章目录flink大数据处理二、WebUI可视化界面&#xff08;测试用&#xff09;三、Flink部署3.1 JobManager3.2 TaskManager3.3 并行度的调整配置3.4 区分 TaskSolt和parallelism并行度配置四、Source Operator(资源算子)五、Sink Operator(输出算子)六、Flink滑…...

Java面试题(二十三)DCL单例

懒汉式单例 private static SingletonInstance INSTANCE;private SingletonInstance(){}public static SingletonInstance getInstance() {if (INSTANCE null) {INSTANCE new SingletonInstance();}return INSTANCE;}构造方法私有化&#xff0c;然后判断是否为空&#xff0c;…...

UML-类图

一、类 一个类由三个格子组成&#xff0c;从上至下分别表示&#xff1a; 第一格&#xff1a;类名称&#xff08;接口和抽象类&#xff0c;使用斜体&#xff09; 第二格&#xff1a;类的属性&#xff08;成员变量&#xff0c;可以没有&#xff09; 第三格&#xff1a;类的操作&…...

PostgreSQL 数据库和 pgAdmin 4

PostgreSQL 数据库和 pgAdmin 4PostgreSQLPostgreSQL 数据库安装PostgreSQL 数据库安装 (Ubuntu)PostgreSQL 数据库其他系统安装PostgreSQL 数据库快速使用入门登录数据库访问数据库参考pgAdmin 4pgAdmin 4 安装使用 pgAdmin 4 登录数据库参考PostgreSQL PostgreSQL 数据库安装…...

quarkus 搭建与基础开发环境配置总结

quarkus搭建与基础开发环境配置总结 大纲 基础概念quarkus2.13.7脚手架工程配置配置maven3.8.7quarkus快速启动quarkus的三种打包方式quarkus将程序打包为二进制文件window环境下quarkus云原生二进制文件打包环境搭建使用GraalVM-java11替换本地java8运行二进制文件 基础概念…...

扩散模型DDPM开源代码的剖析【对应公式与作者给的开源项目,diffusion model】

扩散模型DDPM开源代码的剖析【对应公式与作者给的开源项目&#xff0c;diffusion model】一、简介二、扩散过程&#xff1a;输入是x_0和时刻num_steps&#xff0c;输出是x_t三、逆扩散过程&#xff1a;输入x_t&#xff0c;不断采样最终输出x_0四、具体参考算法流程图五、模型mo…...

C语言 学生记录管理系统

学生记录管理系统 1--添加 2--删除 3--查询&#xff1a;按姓名 4--查询&#xff1a;按班级 5--查询&#xff1a;按学号 0--退出 请选择操作序号(0—5):1 请输入新学生的学号:1 请输入新学生的…...

【独家】华为OD机试 C 语言解题 - 交换字符

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明本期…...

网络安全平台测试赛 easyphp(phar脏数据处理)

昨天的比赛&#xff0c;14.00-17.00.时间有点紧张&#xff0c;比赛期间没拿下来这道 &#x1f62d;非常痛苦&#xff0c;很顺畅的思路 一步步想下来&#xff0c;卡在最后一步末尾脏数据处理了&#xff0c;最后时间到了 没打通&#xff0c;还需多练 这里本地复现一下&#xff1…...

【python】XML格式文件读写详解

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录XML介绍格式XML与AJAX与HTML区别联系生成XML文件案例用SAX模块处理XML用DOM模块处理XML&#x1f338;I could be bounded in a nutshell and count myself a king of infinite space. 特别鸣谢&#xff1a;…...

理解js的精度问题

参考博客&#xff1a;js精度丢失问题-看这篇文章就够了(通俗易懂)、探寻 JavaScript 精度问题以及解决方案、JavaScript 浮点数陷阱及解法 1 为什么 JavaScript 中所有数字包括整数和小数都只有一种类型 即 Number类型&#xff0c;它的实现遵循 IEEE 754 标准。 符号位S&#…...

蓝桥杯 时间显示

题目 输入输出样例 示例 1 输入 46800999输出 13:00:00示例 2 输入 1618708103123输出 01:08:23评测用例规模与约定 对于所有评测用例&#xff0c;给定的时间为不超过 10^{18}1018 的正整数。 运行限制 最大运行时间&#xff1a;1s最大运行内存: 512M 基础知识 时间的转换…...

qt中设置菜单高度

如题所示&#xff0c;我建立一个菜单&#xff0c;代码如下&#xff0c;但是菜单项的高度太小了&#xff0c; &#xff5b; popupMenu new QMenu(this); QAction *action1 new QAction(tr(“&New1”), this); QAction *action2 new QAction(tr(“&New2”), this); QA…...

测开:前端基础-css页面布局-定位

一 、传统网页布局的三种方式 网页布局的本质–用CSS来摆放盒子&#xff0c;把盒子摆放到相应的位置&#xff0c;css提供了三种传统布局方式&#xff0c;分别是标准流&#xff0c;浮动和定位三种。 二、 定位 2.1 啥是定位 我的理解&#xff0c;就是要把这个元素&#xff0c…...

Servlet中八个监听器介绍

一、监听对象创建的监听器 1、ServletContextListener /*** 用于监听ServletContext对象创建和销毁的监听器* since v 2.3*/public interface ServletContextListener extends EventListener {/*** 对象创建时执行此方法。该方法的参数是ServletContextEvent事件对象&#xf…...

LicenseBox Crack,对服务器的要求最低

LicenseBox Crack,对服务器的要求最低 LicenseBox是用于管理基于PHP的软件、WordPress插件或主题、主题、插件和WordPress的更新和许可的完整软件。它易于安装&#xff0c;对服务器的要求最低&#xff0c;用户友好的界面&#xff0c;无限脚本的使用为您的创造力打开了大门。 Li…...

css中重难点整理(vertical-align)

一、vertical-align 在学习vertical-align的时候&#xff0c;可能会很困惑。即使网上有一大推文章讲veitical-align,感觉看完好像懂了&#xff0c;等自己布局的时候用到vertical-align的时候好像对它又很陌生。这就是我在布局的时候遇到的问题。 本来vertical-align就很不好理…...

javaScript基础面试题 ---宏任务微任务

宏任务微任务一、为什么JS是单线程语言&#xff1f;二、JS是单线程&#xff0c;怎样执行异步代码&#xff1f;1、JS是单线程语言 2、JS代码执行流程&#xff0c;同步执行完&#xff0c;再进行事件循环&#xff08;微任务、宏任务&#xff09; 3、清空所有的微任务&#xff0c;再…...

基于JSP的网上书城

技术&#xff1a;Java、JSP等摘要&#xff1a;随着科技的迅速发展&#xff0c;计算机技术已应用到社会的各个领域。随着计算机技术和通信技术的迅速发展&#xff0c;网络的规模也逐渐增大&#xff0c;网络的元素也随之不断增加&#xff0c;有的利用其通信&#xff0c;有的利用其…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...