C++ Lambda表达式的完整介绍

一、Lambda表达式概述

c++在c++11标准中引入了lambda表达式,一般用于定义匿名函数,lambda表达式(也称为lambda函数)是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法。通常,lambda用于封装传递给算法或异步方法的几行代码 。本文主要介绍Lambda的工作原理以及使用方法。

二、Lambda表达式定义

1、Lambda表达式示例

下例是MS官网上的一个示例:

#include <algorithm>
#include <cmath>

void abssort(float* x, unsigned n) {
    std::sort(x, x + n,
        // Lambda expression begins
        [](float a, float b) {
            return (std::abs(a) < std::abs(b));
        } // end of lambda expression
    );
}

这个实例中直接将排序函数的实现写在应该传递函数的位置,省去了定义排序函数的过程,对于这种不需要复用,且短小的函数,直接传递函数体可以增加代码的可读性。

2、Lambda表达式语法定义

  1. capture 子句(在 C++ 规范中也称为 Lambda 引导。)

  2. 参数列表(可选)。 (也称为 Lambda 声明符)

  3. mutable 规范(可选)。

  4. exception-specification(可选)。

  5. return-type 返回值(可选)。

  6. Lambda 体。

3、Lambda表达式参数详解

1)捕获列表

上面介绍完了lambda表达式的各个成分,其实很多部分和正常的函数没什么区别,其中最大的一个不同点就是捕获列表。我在刚开始用lambda表达式的时候,还一直以为这个没啥用,只是用一个 [] 来标志着这是一个lambda表达式。后来了解了才知道,原来这个捕获列表如此强大,甚至我觉得捕获列表就是lambda表达式的灵魂。下面先介绍几种常用的捕获方式。

[] 什么也不捕获,无法lambda函数体使用任何

[=] 按值的方式捕获所有变量

[&] 按引用的方式捕获所有变量

[=, &a] 除了变量a之外,按值的方式捕获所有局部变量,变量a使用引用的方式来捕获。这里可以按引用捕获多个,例如 [=, &a, &b,&c]。这里注意,如果前面加了=,后面加的具体的参数必须以引用的方式来捕获,否则会报错。

[&, a] 除了变量a之外,按引用的方式捕获所有局部变量,变量a使用值的方式来捕获。这里后面的参数也可以多个,例如 [&, a, b, c]。这里注意,如果前面加了&,后面加的具体的参数必须以值的方式来捕获。

[a, &b] 以值的方式捕获a,引用的方式捕获b,也可以捕获多个。

[this] 在成员函数中,也可以直接捕获this指针,其实在成员函数中,[=]和[&]也会捕获this指针。

    class A
    {
        public:
            int i_ = 0;

        void func(int x, int y)
        {
            auto x1 = []{ return i_; };                    // error,没有捕获外部变量
            auto x2 = [=]{ return i_ + x + y; };           // OK,捕获所有外部变量
            auto x3 = [&]{ return i_ + x + y; };           // OK,捕获所有外部变量
            auto x4 = [this]{ return i_; };                // OK,捕获this指针
            auto x5 = [this]{ return i_ + x + y; };        // error,没有捕获x、y
            auto x6 = [this, x, y]{ return i_ + x + y; };  // OK,捕获this指针、x、y
            auto x7 = [this]{ return i_++; };              // OK,捕获this指针,并修改成员的值
        }
    };

    int a = 0, b = 1;
    auto f1 = []{ return a; };               // error,没有捕获外部变量
    auto f2 = [&]{ return a++; };            // OK,捕获所有外部变量,并对a执行自加运算
    auto f3 = [=]{ return a; };              // OK,捕获所有外部变量,并返回a
    auto f4 = [=]{ return a++; };            // error,a是以复制方式捕获的,无法修改
    auto f5 = [a]{ return a + b; };          // error,没有捕获变量b
    auto f6 = [a, &b]{ return a + (b++); };  // OK,捕获a和b的引用,并对b做自加运算
    auto f7 = [=, &b]{ return a + (b++); };  // OK,捕获所有外部变量和b的引用,并对b做自加运算

2)参数列表

Lambda 既可以捕获变量,也可以接受输入参数。 参数列表(在标准语法中称为 Lambda 声明符)是可选的,它在大多数方面类似于函数的参数列表。

auto function = [] (int first, int second){
    return first + second;
};
	
function(100, 200);

3)可变规格mutable

​ mutable修饰符, 默认情况下Lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空)。

#include <iostream>
using namespace std;

int main()
{
   int m = 0;
   int n = 0;
   [&, n] (int a) mutable { m = ++n + a; }(4);
   cout << m << endl << n << endl;
}

4)异常说明

​ 你可以使用 throw() 异常规范来指示 lambda 表达式不会引发任何异常。与普通函数一样,如果 lambda 表达式声明 C4297 异常规范且 lambda 体引发异常,Visual C++ 编译器将生成警告 throw() 。

int main() // C4297 expected 
{ 
 	[]() throw() { throw 5; }(); 
}

5)返回类型

​ Lambda表达式的返回类型会自动推导。除非你指定了返回类型,否则不必使用关键字。返回型类似于通常的方法或函数的返回型部分。但是,返回类型必须在参数列表之后,并且必须在返回类型->之前包含类型关键字。如果lambda主体仅包含一个return语句或该表达式未返回值,则可以省略Lambda表达式的return-type部分。如果lambda主体包含一个return语句,则编译器将从return表达式的类型中推断出return类型。否则,编译器将返回类型推导为void。

auto x1 = [](int i){ return i; };

6)Lambda函数体

​ Lambda表达式的lambda主体(标准语法中的复合语句)可以包含普通方法或函数的主体可以包含的任何内容。普通函数和lambda表达式的主体都可以访问以下类型的变量:

- 捕获变量
- 形参变量
- 局部声明的变量
- 类数据成员,当在类内声明**`this`**并被捕获时
- 具有静态存储持续时间的任何变量,例如全局变量
#include <iostream>
using namespace std;

int main()
{
   int m = 0;
   int n = 0;
   [&, n] (int a) mutable { m = ++n + a; }(4);
   cout << m << endl << n << endl;
}

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

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

相关文章

QT以管理员身份运行

以下配置后&#xff0c;QT在QT Creator调试时&#xff0c;或者生成的.exe程序&#xff0c;都将会默认以管理员身份运行。 一、MSVC编译器 1、在Pro文件中添加以下代码&#xff1a; QMAKE_LFLAGS /MANIFESTUAC:\"level\requireAdministrator\ uiAccess\false\\" …

vue 标题文字字数过长超出部分用...代替 动态显示

效果: 浏览器最大化: 浏览器缩小: 代码: html: <div class"title overflow">{{item.name}}</div> <div class"content overflow">{{item.content}}</div> css: .overflow {/* 一定要加宽度 */width: 90%;/* 文字的大小 */he…

JMeter命令行执行+生成HTML报告

1、为什么用命令行模式 使用GUI方式启动jmeter&#xff0c;运行线程较多的测试时&#xff0c;会造成内存和CPU的大量消耗&#xff0c;导致客户机卡死&#xff1b; 所以一般采用的方式是在GUI模式下调整测试脚本&#xff0c;再用命令行模式执行&#xff1b; 命令行方式支持在…

04-4_Qt 5.9 C++开发指南_时间日期与定时器

文章目录 1. 时间日期相关的类2. 源码2.1 可视化UI设计2.2 dialog.h2.3 dialog.cpp 1. 时间日期相关的类 时间日期是经常遇到的数据类型&#xff0c;Qt 中时间日期类型的类如下。 QTime:时间数据类型&#xff0c;仅表示时间&#xff0c;如 15:23:13。 QDate:日期数据类型&…

jmeter 5.1彻底解决中文上传乱码

1.修改源码,然后重新打jar包,就是所有上传文件名重新获取文件名 参考链接:多种Jmeter中文乱码问题处理方法 - 51Testing软件测试网 2.修改Advanced,必须选java

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)--功能实现[五]

文章目录 SSM--功能实现实现功能09-带条件查询分页显示列表需求分析/图解思路分析代码实现测试分页条件查询带条件分页查询显示效果 实现功能10-添加家居表单前端校验需求分析/图解思路分析代码实现完成测试测试页面效果 实现功能11-添加家居表单后端校验需求分析/图解思路分析…

第八次作业

1、什么是数据认证&#xff0c;有什么作用&#xff0c;有哪些实现的技术手段&#xff1f; 数据认证的官方回答&#xff1a;数字认证证书它是以数字证书为核心的加密技术可以对网络上传输的信息进行加密和解密、数字签名和签名验证&#xff0c;确保网上传递信息的安全性、完整性…

Squeeze-and-Excitation Networks阅读笔记一

文章目录 Abstract1 INTRODUCTION Abstract 卷积算子&#xff08;convolution operator&#xff09;是卷积神经网络&#xff08;cnn&#xff09;的核心组成部分&#xff0c;它使网络能够通过融合每层局部接受域内的空间和通道信息来构建信息特征。广泛的先前研究已经调查了这种…

CSS调色网有哪些

本文章转载于湖南五车教育&#xff0c;仅用于学习和讨论&#xff0c;如有侵权请联系 1、https://webgradients.com/ Wbgradients 是一个在线调整渐变色的网站 &#xff0c;可以根据你想要的调整效果&#xff0c;同时支持复制 CSS 代码&#xff0c;可以更好的与开发对接。 Wbg…

今天开始学习如何正式调查

本节要讲解三个内容 样本容量 调查方式 调查问卷的回收 在正式调查之前需要确定样本容量 就说要准备调查多少人确定好样本容量之后又要考虑设计的调查问卷 是以什么样的方式发出去 问卷的回收又要注意什么问题 要讲的主要内容 先看样本容量 样本容量确定的基本原…

IO(JavaEE初阶系列8)

目录 前言&#xff1a; 1.文件 1.1认识文件 1.2结构和目录 1.3文件路径 1.4文本文件vs二进制文件 2.文件系统的操作 2.1Java中操作文件 2.2File概述 2.2.1构造File对象 2.2.2File中的一些方法 3.文件内容的操作 3.1字节流 3.1.1InPutStream的使用方法 3.1.2OutPu…

UEditorPlus v3.3.0 图片上传压缩重构,UI优化,升级基础组件

UEditor是由百度开发的所见即所得的开源富文本编辑器&#xff0c;基于MIT开源协议&#xff0c;该富文本编辑器帮助不少网站开发者解决富文本编辑器的难点。 UEditorPlus 是有 ModStart 团队基于 UEditor 二次开发的富文本编辑器&#xff0c;主要做了样式的定制&#xff0c;更符…

Unity 实现字幕打字效果

Text文本打字效果&#xff0c;TextMeshPro可以对应参考&#xff0c;差距不大&#xff0c;改改参数名就能用。改脚本原本被我集成到其他的程序集中&#xff0c;现在已经分离。 效果 实现功能 1.能够设置每行能够容纳的字数和允许的冗余 2.打字效果 3.每行打完上移 4.开头进入&…

Markdown系列之Flowchat流程图

一.欢迎来到我的酒馆 介绍Markdown的Flowchart流程图语法。 目录 一.欢迎来到我的酒馆二.什么是Flowchart三.更进一步 二.什么是Flowchart 2.1 Flowchart是一款基于javascript的工具&#xff0c;使用它可以用代码创建简单的流程图。具体信息可以查看flowchart官网&#xff1a;…

栈和队列的实现

Lei宝啊&#xff1a;个人主页&#xff08;也许有你想看的&#xff09; 愿所有美好不期而遇 前言 &#xff1a; 栈和队列的实现与链表的实现很相似&#xff0c;新瓶装旧酒&#xff0c;没什么新东西。 可以参考这篇文章&#xff1a; -------------------------无头单向不循环…

微信小程序开发【从0到1~入门篇】2023.08

一个小程序主体部分由三个文件组成&#xff0c;必须放在项目的根目录&#xff0c;如下&#xff1a; 文件必须作用app.js是小程序逻辑app.json是小程序公告配置app.wxss否小程序公告样式表 3. 小程序项目结构 一个小程序页面由四个文件组成&#xff0c;分别是&#xff1a; 文…

并查集维护额外信息,算法思路类似前缀和,结构类似扑克接龙

一、链接 240. 食物链 二、题目 动物王国中有三类动物 A,B,CA,B,C&#xff0c;这三类动物的食物链构成了有趣的环形。 AA 吃 BB&#xff0c;BB 吃 CC&#xff0c;CC 吃 AA。 现有 NN 个动物&#xff0c;以 1∼N1∼N 编号。 每个动物都是 A,B,CA,B,C 中的一种&#xff0c;…

Nginx使用proxy_cache指令设置反向代理缓存静态资源

场景 CentOS7中解压tar包的方式安装Nginx&#xff1a; CentOS7中解压tar包的方式安装Nginx_centos7 tar文件 怎么load_霸道流氓气质的博客-CSDN博客 参考上面流程实现搭建Nginx的基础上&#xff0c;实现静态资源的缓存设置。 注意上面安装时的目录是在/opt/nginx目录下&…

数组的学习

数组学习 文章目录 数组来由数组的使用数组的内存图变量声明和args参数说明声明分配空间值的省略写法数组的length属性数列输出求和判断购物金额结算Arrays的sort和toString方法Arrays的equals和fill和copyOf和binarySearch方法字符数组顺序和逆序输出 数组来由 录入30个学生…

Linux(进程)

Linux&#xff08;进程&#xff09; 1. 冯诺依曼结构体系2 . 操作系统&#xff08;OS&#xff09;3.进程task_ struct内容分类查看进程查看PID以及PPIDfork()Linux操作系统进程的状态僵尸进程孤儿进程进程优先级其他概念 1. 冯诺依曼结构体系 冯诺依曼结构也称普林斯顿结构&am…