STL——Lambad表达式

news2024/11/15 14:09:51

在这里插入图片描述

📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段>——目标Windows,MySQL,Qt,数据结构与算法,Linux,多线程,会持续分享学习成果和小项目的
📖作者主页:热爱编程的小K
📖专栏链接:c++

🎉欢迎各位→点赞👏 + 收藏💞 + 留言🔔​
💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🐾

在这里插入图片描述

文章目录

    • Lambad表达式
      • 一、Lambda表达式语法
        • 1、Lambda捕获列表详解
        • 2、Lambda参数列表
        • 3、可变规格mutable
        • 4、异常说明
        • 5、返回类型
      • 二、Lambda表达式的优缺点
        • 1、优点
        • 2、缺点
      • 三、Lambda表达式工作原理
      • 四、操作基本数据类型
      • 五、操作自定义类型->this以及find_if仿函数的应用


Lambad表达式

Lambda表达式是现代C++在C ++ 11和更高版本中的一个新的语法糖 。 lambda表达式(也称为lambda函数)是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法。通常,lambda用于封装传递给算法或异步方法的几行代码 。

Lambda有很多叫法,有Lambda表达式、Lambda函数、匿名函数,为了方便表述统一用Lambda表达式进行叙述。

一、Lambda表达式语法

语法如下:

[capture list](parameters)mutable noexcept ->return type
{
    statement;
}
  • 捕获列表(capture list):捕获列表能够捕捉上下文中的变量以供Lambda函数使用。

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

  • 异常说明(noexcept) :用于Lamdba表达式内部函数是否可以抛出异常。

  • 返回类型(return type):追踪返回类型(也叫尾拖返回类型)形式声明函数的返回类型。我们可以在不需要返回值的时候也可以连同符号”->”一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。

  • 函数体(statement):内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。

1、Lambda捕获列表详解

Lambda表达式与普通函数最大的区别是,除了可以使用参数以外,Lambda函数还可以通过捕获列表访问一些上下文中的数据。具体地,捕捉列表描述了上下文中哪些数据可以被Lambda使用,以及使用方式(以值传递的方式或引用传递的方式)。语法上,在“[]”包括起来的是捕获列表,捕获列表由多个捕获项组成,并以逗号分隔。捕获列表有以下几种形式:

  • [ ]中没有任何捕获,表示不捕获任何外部变量

    auto function = ([]{
    		std::cout << "Hello World!" << std::endl;
    	}
    );
    function();
    
  • [var]表示按值捕获指定的的变量var

    int num = 100;
    auto function = ([num]{
    		std::cout << num << std::endl;
    	}
    );
    function();
    
  • [=]表示值传递方式捕获所有父作用域的变量(包括this指针)

    int index = 1;
    int num = 100;
    auto function = ([=]{
    			std::cout << "index: "<< index << ", " 
                    << "num: "<< num << std::endl;
    	}
    );
    function();
    
  • [&var]表示按引用捕获指定的变量var

    int num = 100;
    auto function = ([&num]{
    		num = 1000;
    		std::cout << "num: " << num << std::endl;
    	}
    );
    function();
    
  • [&]表示按引用捕获所有父作用域的变量(包括this)

    int index = 1;
    int num = 100;
    auto function = ([&]{
    		num = 1000;
    		index = 2;
    		std::cout << "index: "<< index << ", " 
                << "num: "<< num << std::endl;
    	}
    );
    
    function();
    
  • [this]表示值传递方式捕获当前的this指针

    #include <iostream>
    using namespace std;
     
    class Lambda
    {
    public:
        void sayHello() {
            std::cout << "Hello" << std::endl;
        };
    
        void lambda() {
            auto function = [this]{ 
                this->sayHello(); 
            };
    
            function();
        }
    };
     
    int main()
    {
        Lambda demo;
        demo.lambda();
    }
    

=、&混合搭配

  • [=,&a,&b]表示按引用捕获变量a和b,按值捕获其他所有变量

    int index = 1;
    int num = 100;
    auto function = ([=, &index, &num]{
    		num = 1000;
    		index = 2;
    		std::cout << "index: "<< index << ", " 
                << "num: "<< num << std::endl;
    	}
    );
    
    function();
    
  • [=,a]这里已经以值传递方式捕捉了所有变量,但是重复捕捉a了,会报错的;

  • [&,&this]这里&已经以引用传递方式捕捉了所有变量,再捕捉this也是一种重复。

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

二、Lambda表达式的优缺点

1、优点

  1. 可以直接在需要调用函数的位置定义短小精悍的函数,而不需要预先定义好函数

  2. 使用Lamdba表达式变得更加紧凑,结构层次更加明显、代码可读性更好

2、缺点

  1. Lamdba表达式语法比较灵活,增加了阅读代码的难度

  2. 对于函数复用无能为力(在不同的作用域中,无法复用)

三、Lambda表达式工作原理

编译器会把一个Lambda表达式生成一个匿名类的匿名对象,并在类中重载函数调用运算符,实现了一个operator()方法。

auto print = []{cout << "Hello World!" << endl; };

编译器会把上面这一句翻译为下面的代码:

class Labmda_1
{
public:
	void operator()(void) const
	{
		cout << "Hello World!" << endl;
	}
};
// 用构造的类创建对象,print此时就是一个函数对象
auto print = print_class();

四、操作基本数据类型

总结:用值的方式捕获,函数的打印结果和第一个调用时打印结果一样。不会因为变量的改变,函数的调用结果改变

cout << "正常调用函数指针" << "\t";
	int(*p)(int, int) = Max;
	cout << p(1, 2) << endl;
	cout << "完整版本调用lambad表达式" << "\t";
	cout << [](int a, int b)->int {return a > b ? a : b; }(1, 2) << endl;
	cout << "缺省版本" << "\t";
	auto f1 = []() {"无返回值,无参数的函数"; };
	f1();
	cout << "捕获方式" << endl;
	int a = 1, b = 2;
	/*auto k = []() {cout << a << b; };
	错误,不能用外部的值a,b*/
	auto k = [=]() {/*a = 123;错误,按值的方式不能修改*/ cout << a <<"\t" << b; };
	k();
	cout << endl;
	auto king = [&]() {a = 123; cout << a << "\t" << b; };
	king();
	//总结:用值的方式捕获,函数的打印结果和第一个调用时打印结果一样。不会因为变量的改变,函数的调用结果改变
	cout << endl << a << endl;  //打印123
	k();  //打印1

五、操作自定义类型->this以及find_if仿函数的应用

给find_if函数中的比较准则提供了一个胆小精悍的方法

class MM 
{
public:
	MM(string name = " ", int age = 0) :name(name), age(age) {}
	string getName()const { return name; }
	int getAge() const { return age; }
	void printData() {
		auto func = [this]() {cout << name << "\t" << age << endl; };
		func();
	}
protected:
	string name;
	int age;
};
int main() 
{
	MM mm;
	mm.printData();
	list<MM> info;
	info.push_back(MM("妲己", 18));
	info.push_back(MM("吕布",19));
	info.push_back(MM("貂蝉", 28));
	string name;
	cin >> name;
	list<MM>::iterator iter = find_if(info.begin(), info.end(), [=](const MM& object) {return object.getName() == name; });
	if (iter != info.end()) {
		iter->printData();
	}
	return 0;
}

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

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

相关文章

【C语言】输入输出、字符串操作、内存操作、文件操作函数

三对基本输入输出函数 1.gets()&#xff0c;puts() gets()从标准输入中获取一个字符串&#xff0c;到str&#xff08;自己创建的char型数组&#xff09;中&#xff0c;读到换行或输入末尾结束获取r&#xff1b; 成功返回str&#xff0c;失败返回空。 char *gets(char *str)…

ARM汇编第一次上机(顺序、分支、单重循环)【嵌入式系统】

ARM汇编第一次上机&#xff08;顺序、分支、单重循环&#xff09;【嵌入式系统】 前言推荐说明ARM汇编第一次上机&#xff08;顺序、分支、单重循环&#xff09;内容1 sum1流程图代码编写结果分析 2 sum2流程图代码编写结果分析 3 numbers流程图代码编写结果分析 最后 前言 20…

Python统计学:配对样本t检验~均值差的检验

配对样本 t检验 用于两个不同条件下&#xff0c;对同一对象进行测量所得的两个样本均值的区别。 比如吃药前和吃药后体温是否有变化&#xff0c;大鱼钩和小鱼钩钓的鱼的体长是否有差异等。 配对样本是什么&#xff1f; 配对样本需要满足两个基本条件&#xff1a; 1. 样本间存…

Java版本工程管理系统软件源码 自主研发,工程行业适用

Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下&#xff1a; 首页 工作台&#xff1a;待办工作、消息通知、预警信息&#xff0c;点击可进入相应的列表 项目进度图表&#xff1a;选择&#xff08;总体或单个&#xff09;项目显示…

【Java 数据结构】PriorityQueue(堆)的使用及源码分析

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

ES配置与使用

一、单机版安装 地址&#xff1a;www.elastic.co 下载tar格式&#xff0c;或者复制链接&#xff0c;wget url下载 启动&#xff1a; ./bin/elasticsearch 二、插件 解决页面问题&#xff0c;GitHub下载&#xff1a;elasticsearch-head 需要node环境。node -v检查node版本…

TryHackMe-Jack(boot2root)

Jack 破坏运行Wordpress的Web服务器&#xff0c;获得低特权用户&#xff0c;并使用Python模块将您的权限升级到root。 端口扫描 循例nmap web枚举 robots.txt wpscan枚举user wpscan直接爆 得到wendy的密码 直接登后台 根据题目提示&#xff0c;利用user role editor帮助我们…

使用chatgpt写一个划词翻译的浏览器插件

最近在网上流行的chatgpt&#xff0c;实在是太火了&#xff0c;好多人在使用&#xff0c;而且它的用处实在是太丰富了&#xff0c;能帮助我们解决很多问题&#xff0c;就比如说&#xff1a;编程&#xff0c;生成图片&#xff0c;翻译等。太丰富了。我看网上很多人都在说&#x…

江苏三年制专转本本法学类考纲配套课程及复习资料

法学类专业课内容比较多&#xff0c;需要背的也很多&#xff0c;今天我来给大家看一下我们应该如何学习法学类&#xff1f;01&#xff1a;考试科目考试科目&#xff1a;大学语文专业课基础理论考试课程A &#xff1a;法理学约 15%课程B&#xff1a;宪法学 约 15%课程C &#xf…

第九讲 常用数据结构之列表-2

列表的方法 列表类型的变量拥有很多方法可以帮助我们操作一个列表&#xff0c;假设我们有名为foos的列表&#xff0c;列表有名为bar的方法&#xff0c;那么使用列表方法的语法是&#xff1a;foos.bar()&#xff0c;这是一种通过对象引用调用对象方法的语法。后面我们讲面向对象…

接口自动化【三】(接口依赖之上传图片;Template 模块用法)

前言 一、后台上传图片接口 二、用postman来做这种有依赖的接口 三、使用 Template 模块进行字符串的替换 四、使用 Template 模块进行字符串的替换&#xff08;针对于Excel表格中的数据&#xff09; 总结 前言 本章中&#xff0c;对接口的依赖做了阐述&#xff0c;后台上…

怎么用Elai智能数字人来直播带货?

随着直播带货的火爆&#xff0c;越来越多的商家和品牌想要借助这一新兴的营销方式来提升销量和品牌影响力。但是&#xff0c;直播带货也面临着一些挑战&#xff0c;比如真人主播的成本高、稳定性差、风险大等。那么&#xff0c;有没有一种更好的解决方案呢&#xff1f;Elai智能…

leetcode重点题目分类别记录(三)动态规划深入

文章目录 动态规划背包问题01背包抽象出求解目标尝试进程子问题拆分基本情况根据拆分过程定义dp数组与转移方程遍历顺序与状态压缩模板归纳题目应用变种提升组合问题多维01背包有特殊限制的01背包 完全背包尝试进行子问题拆分转移方程题目应用变种提升-求组合/排列数 打家劫舍变…

【案例教程】CMIP6数据处理方法与典型案例分析实践技术

气候变化关系到农业、生态系统、社会经济和人类生存与发展&#xff0c;是当今世界关注的重点问题之一。IPCC&#xff08;Intergovernmental Panel on Climate Change&#xff09;第6次评估报告指出&#xff0c;自 20 世纪 50 年代以来&#xff0c;从全球平均气温和海温升高、大…

LightGBM^v^

LightGBM LightGBM&#xff08;Light Gradient Boosting Machine&#xff09;是一个基于梯度提升决策树&#xff08;GBDT&#xff09;的高效机器学习框架。它是由微软公司开发的&#xff0c;旨在提供更快、更高效的训练和预测性能。LightGBM在许多数据科学竞赛中都表现出色&am…

什么品牌的蓝牙耳机通话音质最好?通话音质好的蓝牙耳机

使用蓝牙耳机&#xff0c;无需取下耳机即可接听电话&#xff0c;来电时只需按一个按钮即可开始讲话&#xff0c;可以说是十分方便&#xff0c;为了帮助您找到可以帮助您拨打和接听电话的耳机&#xff0c;我们收集了适合通话的蓝牙耳机。 一、南卡小音舱Lite2蓝牙耳机 动圈单元…

亚马逊巴西站对中国商家正式开放试运营,如何快速提升销量

近日&#xff0c;亚马逊全球开店宣布&#xff0c;亚马逊巴西站对中国商家正式开放试运营&#xff0c;在亚马逊巴西站试运营期间&#xff0c;亚马逊卖家是能获得很多扶持的&#xff0c;比如说大量额外引流资源支持&#xff0c;营销方面&#xff0c;巴西卖家是可以使用优惠券&…

Three.js教程:透视投影相机

推荐&#xff1a;将NSDT场景编辑器加入你的3D工具链。 其他系列工具&#xff1a;NSDT简石数字孪生 Threejs如果想把三维场景Scene渲染到web网页上&#xff0c;还需要定义一个虚拟相机Camera&#xff0c;就像你生活中想获得一张照片&#xff0c;需要一台用来拍照的相机。 透视…

恶意软件及反病毒的一些知识

目录标题 什么是恶意软件&#xff1f;恶意软件的特征恶意软件可以分为几类&#xff1f;按照传播方式分类按照功能分类 恶意软件的免杀技术有哪些&#xff1f;文件免杀内存免杀行为免杀 反病毒技术有哪些&#xff1f;单击反病毒网关反病毒 反病毒网关的工作原理反病毒网关的工作…

OpenText Exceed TurboX (ETX) 安全功能介绍

OpenText Exceed TurboX (ETX) 安全功能介绍 将所有重要的知识产权&#xff08;IP &#xff09;相关数据保存在受良好保护的中央数据中心是保护 IP 的最佳做法。安全的远程访问是保护知识产权的关键。 所有数据流量均采用最新标准加密技术进行加密ETX 整合多种身份验证系统ET…