C++ Lambda表达式基础用法

语法

C++11标准lambda表达式的语法非常简单,定义如下,并且语法规定lambda表达式如果存在说明符,那么形参列表不能省略。标准还规定能捕获的变量必须是一个自动存储类型。简单来说就是非静态的局部变量、非全局变量。

定义:[ captures ] ( params ) specifiers exception -> ret { body }

例如:
[x](int y)->int { return x * y; }

[ captures ] —— 捕获列表

它可以捕获当前函数作用域的零个或多个变量,变量之间用逗号分隔。另外,捕获列表的捕获方式有两种:按值捕获和引用捕获。
 捕获引用的语法与捕获值只有一个&的区别,要表达捕获引用我们只需要在捕获变量之前加上&,类似于取变量指针。
只不过这里捕获的是引用而不是指针,在lambda表达式内可以直接使用变量名访问变量而不需解引用,比如:

int main()
{
    int x = 5, y = 8;
    auto foo = [&x, &y] { return x * y; };
}

( params ) —— 可选参数列表

语法和普通函数的参数列表一样,在不需要参数的时候可以忽略参数列表。


specifiers —— 可选限定符

C++11中可以用mutable,它允许我们在lambda表达式函数体内改变按值捕获的变量,或者调用非const的成员函数。


exception —— 可选异常说明符

我们可以使用noexcept来指明lambda是否会抛出异常。


ret —— 可选返回值类型

不同于普通函数,lambda表达式使用返回类型后置的语法来表示返回类型如果没有返回值(void类型),可以忽略包括->在内的整个部分。另外,我们也可以在有返回值的情况下不指定返回类型,这时编译器会为我们推导出一个返回类型。对应到上面的例子是->int。


{ body } —— lambda表达式的函数体

这个部分和普通函数的函数体一样。对应例子中的{ return x * y; }。

捕获变量作用域例子

int x = 0;
int main()
{
    int y = 0;
    static int z = 0;
    auto foo = [x, y, z] {};
}

以上代码可能是无法通过编译的,其原因有两点:第一,变量x和z不是自动存储类型的变量;第二,x不存在于lambda表达式定义的作用域。这里可能无法编译,因为不同编译器对于这段代码的处理会有所不同,比如GCC就不会报错,而是给出警告。

对于全局变量或者静态局部变量,其实不必这么麻烦,直接在lambda函数体内用就行了。

int x = 1;
auto foo = [] { return x; };
int main()
{
    foo();
}

如果我们将一个lambda表达式定义在全局作用域,那么lambda表达式的捕获列表必须为空。因为根据上面提到的规则,捕获列表的变量必须是一个自动存储类型,但是全局作用域并没
有这样的类型。

捕获值和捕获引用例子

捕获值是将函数作用域的x和y的值复制到lambda表达式对象的内部,就如同lambda表达式的成员变量一样。

捕获引用的语法与捕获值只有一个&的区别,要表达捕获引用我们只需要在捕获变量之前加上&。在lambda表达式内可以直接使用变量名访问变量而不需解引用,比如:

int main()
{
    int x = 5, y = 8;
    auto foo = [&x, &y] { return x * y; };
}

接下来我们再看另外一个例子 

void bar1()
{
    int x = 5, y = 8;
    auto foo = [x, y] {
        x += 1;// 编译失败,无法改变捕获变量的值
        y += 2;// 编译失败,无法改变捕获变量的值
        return x * y;
    };
    std::cout << foo() << std::endl;
}

void bar2()
{
    int x = 5, y = 8;
    auto foo = [&x, &y] {
        x += 1;
        y += 2;
        return x * y;
    };
    std::cout << foo() << std::endl;
}


void bar3()
{
    int x = 5, y = 8;
    auto foo = [x, y] () mutable {
        x += 1;
        y += 2;
        return x * y;
    };
    std::cout << foo() << std::endl;
}

在上面的代码中函数bar1无法通过编译,原因是我们无法改变捕获变量的值。这就引出了lambda表达式的一个特性:捕获的变量默认为常量,或者说lambda是一个常量函数(类似于常量成员函数)。bar2函数里的lambda表达式能够顺利地通过编译,是我们在函数体内改变的并不是引用本身,而是引用的值,所以并没有被编译器拒绝。 使用mutable说明符可以移除lambda表达式的常量性,也就是说我们可以在lambda表达式的函数体中修改捕获值的变量了,例如bar3,但是要注意我们修改的是捕获变量的复制,不会影响外部变量。而捕获引用则不同,在lambda表达式内修改捕获引用的变量,对应的外部变量也会被修改。

特殊的捕获方法

lambda表达式的捕获列表除了指定捕获变量之外还有3种特殊的捕获方法。
1.[this] —— 捕获this指针,捕获this指针可以让我们使用this类型的成员变量和函数。
2.[=] —— 捕获lambda表达式定义作用域的全部变量的值包括this
3.[&] —— 捕获lambda表达式定义作用域的全部变量的引用包括this

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

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

相关文章

纳米流体传热与计算机模拟

纳米流体传热与计算机模拟 一、引言 纳米流体传热是一个研究领域&#xff0c;主要关注纳米尺度下流体的传热特性和机制。由于纳米流体的尺寸较小&#xff0c;其传热行为与传统尺度下的流体有很大不同。近年来&#xff0c;随着计算机技术的飞速发展&#xff0c;计算机模拟成为…

TensorFlow(2):Windows安装TensorFlow

1 安装python环境 这一步请自行安装&#xff0c;这边不做介绍。 2 安装anaconda 下载路径&#xff1a;Index of /&#xff0c;用户自行选择自己的需要的版本。 3 环境配置 3.1 anaconda环境配置 找到设置&#xff0c;点击系统->系统信息->高级系统设置->环境变量…

Github 2023-12-19开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2023-12-19统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目4Rust项目2非开发语言项目2C#项目1TypeScript项目1 Avalonia: 跨平台UI框架和Avalonia XPF 创建周…

高高。。。。

重点&#xff1a;存储系统/分布式系统 得到数据&#xff1a; 数据模型计算&#xff08;简单系统&#xff09;实现一个操作系统CPU&#xff08;成本高&#xff09;仿真实验 文章类型&#xff1a; 国际会议 10-15slices期刊论文 做OS研究为其他方面提供支持 一 Advanced OS …

鸿蒙开发运用ArkUI基础-实操显式动画

利用ArkUI组件不仅可以实现属性变化引起的属性动画&#xff0c;也可以实现父组件状态变化引起子组件产生动画效果&#xff0c;这种动画为显式动画。效果如图所示&#xff1a; 代码结构解读 ├──entry/src/main/ets // 代码区 │ ├──common │ │ └──…

css 美化滚动条

当div内容溢出容器定义的高度时,滚动条显示,并美化默认的滚动条样式 div 容器 <divclass"content">内容 </div>css 样式 /* 问话区域 滚动条 */ .content {overflow: auto;height: 662px;padding: 25px;scrollbar-width: thin; /* 设置滚动条宽度 */bo…

四川云汇优想教育咨询有限公司电商服务靠谱吗

随着抖音电商的兴起&#xff0c;越来越多的商家开始关注这一领域。四川云汇优想教育咨询有限公司作为一家专注于电商服务的企业&#xff0c;也受到了广泛的关注。那么&#xff0c;四川云汇优想教育咨询有限公司的抖音电商服务靠谱吗&#xff1f;下面我们将从多个方面进行深入剖…

大模型赋能“AI+电商”,景联文科技提供高质量电商场景数据

据新闻报道&#xff0c;阿里巴巴旗下淘天集团和国际数字商业集团都已建立完整的AI团队。 淘天集团已经推出模特图智能生成、官方客服机器人、万相台无界版等AI工具&#xff0c;训练出了自己的大模型产品 “星辰”&#xff1b; 阿里国际商业集团已成立AI Business&#xff0c;…

在线教育(内部)培训系统搭建,提供高效便捷的学习体验

我国一直是教育大国&#xff0c;不管是国民义务教育&#xff0c;还是学历提升、职业证书等&#xff0c;我国教育行业一直处于兴盛不衰的地步。 随着互联网信息化的发展&#xff0c;在线教育培训系统逐渐在教育行业得到重视。根据数据显示&#xff0c;我国在线教育市场规模将达…

拼图游戏

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 然后是创建类 创建一个代码类 和一个运行类 代码如下&#xff1a; package heima;import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import jav…

探索泰勒级数在机器学习中的作用:从函数逼近到模型优化

一、介绍 泰勒级数是数学中的一个基本概念&#xff0c;在机器学习领域有着重要的应用。本文将探讨泰勒级数的基础知识、它在机器学习中的相关性以及一些具体应用。 揭开复杂性&#xff1a;利用泰勒级数增强机器学习应用的理解和效率。 二、理解泰勒级数 在数学中&#xff0c;泰…

Leetcode—128.最长连续序列【中等】

2023每日刷题&#xff08;六十四&#xff09; Leetcode—128.最长连续序列 实现代码 class Solution { public:int longestConsecutive(vector<int>& nums) {unordered_set<int> s;for(auto num: nums) {s.insert(num);}int longestNum 0;for(auto num: s) …

Python Opencv实践 - 手部跟踪

使用mediapipe库做手部的实时跟踪&#xff0c;关于mediapipe的介绍,请自行百度。 mediapipe做手部检测的资料&#xff0c;可以参考这里&#xff1a; MediaPipe Hands: On-device Real-time Hand Tracking 论文阅读笔记 - 知乎论文地址&#xff1a; https://arxiv.org/abs/2006…

Shell三剑客:awk(简介)

一、前言 AWK 是一种编程语言&#xff0c;用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件&#xff0c;或其它命令的输出。它支持用户自定义函数和动态正则表达式等先进功能&#xff0c;是linux/unix下的一个强大编程工具。它在命令行中使用&a…

3 - Electron app BrowserWindow对象-关于窗口

优雅的打开应用~ 当加载缓慢&#xff0c;打开应用的一瞬间会出现白屏&#xff0c;以下方法可以解决 const mainWindow new BrowserWindow({ show: false }) mainWindow.once(ready-to-show, () > {mainWindow.show() }) 设置背景颜色 const win new BrowserWindow({ b…

VueCron使用方法

1&#xff09;什么是vueCron Vue Cron 是基于 Vue.js 的定时任务管理组件&#xff0c;它提供了一种简单易用的方式来设定和管理定时任务。Vue Cron 提供了一个类似于 Linux crontab 的界面&#xff0c;用户可以通过它来创建、编辑和删除定时任务。 2&#xff09;安装依赖及应…

FreeCodeCamp--数千免费编程入门教程,非盈利性网站,质量高且支持中文

在浏览话题“Github上获得Star最多的项目”时&#xff0c;看到了FreeCodeCamp&#xff0c;顾名思义--免费编程营地&#xff0c;于是就做了些调研&#xff0c;了解了下这是个什么项目 这是一个致力于推动编程教育的非营利性组织&#xff0c;团队由来自世界各地的杰出的技术开发…

如何将图片转为PDF

问题描述&#xff1a;如何将图片转为PDF&#xff0c;有时需要将纸质文档扫描成PDF&#xff0c;然后上传到网上。 解决办法&#xff1a;平时使用的方法是将图片插入到word文件中&#xff0c;然后将图片设置为浮于文字下方&#xff0c;然后调整图片的大小&#xff0c;铺满整个wo…

SMART PLC MODBUS-RTU通信(多台同一设备通信优化写法)

MODBUS通信基础介绍请查看下面文章链接: https://rxxw-control.blog.csdn.net/article/details/133755924https://rxxw-control.blog.csdn.net/article/details/133755924多台同一设备的MODBUS-RTU通信,我们在编写轮询程序的时候,可以采用站号变址的方式实现。 1、轮询状态…

[Linux] Haproxy负载均衡集群

一、Haproxy知识 1.1 常用的负载均衡调度器 软件通常使用开源的LVS、Haproxy、 Nginx LVS性能最好&#xff0c;但是搭建相对复杂&#xff1b;Nginx 的upstream模块支持群集功能&#xff0c;但是对群集节点健康检查功能不强&#xff0c;高并发性能没有Haproxy好。 硬件一般使用…