C++11 Lambda表达式

Lambda表达式简介
 

Lambda表达式是现代C++在C++11和更高版本中的一个新的语法糖。它是一种定义匿名函数对象的便捷方法,常用于封装传递给算法或异步方法的几行代码。Lambda表达式可以在调用或作为函数参数传递的位置处定义,可以捕获上下文中的变量供函数使用。Lambda表达式的语法定义包括捕获列表、参数列表、可变规格、异常说明、返回类型和函数体。捕获列表描述了Lambda函数可以访问的上下文变量及传递方式,参数列表类似于普通函数的参数列表,可变规格用于取消Lambda函数的常量性,异常说明用于指示Lambda函数是否会引发异常,返回类型可以省略让编译器推导,函数体可以包含任意内容。Lambda表达式的优点包括在需要调用函数的位置定义短小精悍的函数,代码紧凑且可读性高。缺点是语法相对灵活增加了阅读难度,对于函数复用有限。Lambda表达式的工作原理是编译器会把Lambda表达式生成一个匿名类的匿名对象,并在类中重载函数调用运算符,实现了一个operator()方法。这样可以用Lambda表达式构造一个函数对象。

 Lambda表达式在C++中的语法定义
 

在C语言中,没有直接支持Lambda表达式的语法。 Lambda表达式是C++11引入的新特性,它允许在函数调用或作为函数参数传递的位置定义匿名函数对象。C++的Lambda表达式的语法定义与函数定义相似,一般形式为:

[捕获列表](参数列表) mutable noexcept -> 返回类型 {函数体}

示例 1 :
 

int main()
{// 两个数相加的lambdaauto add1 = [](int a, int b)->int{return a + b; };cout << add1(1, 2) << endl;// 省略返回值auto add2 = [](int a, int b){return a + b; };cout << add2(1, 2) << endl;return 0;
}

示例2

int main()
{// 交换变量的lambdaint x = 0, y = 1;auto swap1 = [](int& x1, int& x2)->void {int tmp = x1; x1 = x2; x2 = tmp; };swap1(x, y);cout << x << ":" << y << endl;auto swap2 = [](int& x1, int& x2){int tmp = x1;x1 = x2;x2 = tmp;};swap2(x, y);cout << x << ":" << y << endl;// 不传参数交换x y的lambda  -- 捕捉列表// 默认捕捉的对象不能修改/*auto swap3 = [x, y]()mutable{int tmp = x;x = y;y = tmp;};swap3();cout << x << ":" << y << endl;*/auto swap4 = [&x, &y]{int tmp = x;x = y;y = tmp;};swap4();cout << x << ":" << y << endl;return 0;
}

Lambda表达式注意以下几个问题:

一: Lambda表达式的捕获列表有哪些形式?
1. []:表示不捕获任何变量。

int main()
{int a = 9;[]() {cout << a << endl; };system("pause");return 0;
}


2. [var]:表示值传递方式捕获变量var。

int main()
{int a = 9;auto lam = [a]() {cout << a << endl; };lam();return 0;
}


3. [var, &]:表示值传递方式捕获变量var,并通过引用传递方式捕获其他所有变量。

#include <iostream>
using namespace std;
int main()
{int a = 9;int b = 5;int &x = b;x = 8;auto lam = [a, &](){cout << a << " " <<x <<endl;};lam();return 0;
}


4. [=]:表示以值传递的方式捕获所有变量。

int main()
{int a = 9;string s = "hello";auto lam = [=]() {cout << a << " "<<s<<endl; };lam();return 0;
}


5. [&]:表示以引用传递的方式捕获所有变量。

int main()
{int a = 9;auto lam = [&a]() {a = 10; cout << a << endl; };lam();return 0;
}


6. [&, var]:表示以引用传递的方式捕获所有变量,并值传递方式捕获变量var。

int main()
{int a = 9;string s = "hello";auto lam = [&, a]() {s = "hhah"; cout << a << " " << s << endl; };lam();return 0;
}


7. [=, &var]:表示以值传递的方式捕获所有变量,并引用传递方式捕获变量var。

int main()
{int a = 9;string s = "hello";auto lam = [=, &a]() {a = 90; cout << a << " " << s << endl; };lam();return 0;
}

需要注意的是,捕获列表不允许变量重复传递,否则会导致编译时错误。
 

二:Lambda表达式的捕获范围

//捕捉列表的参数来源范围--当前栈帧 (注意全局变量)
int func()
{int a, b, c, d, e;a = b = c = d = e = 1;// 全部传值捕捉auto f1 = [=](){cout << a << b << c << d << e << endl;};f1();// 混合捕捉auto f2 = [=, &a](){a++;cout << a << b << c << d << e << endl;};f2();static int x = 0;if (a){auto f3 = [&, a](){//a++;//errorb++;c++;d++;e++;val++;x++;cout << a << b << c << d << e << endl;};f3();}return 0;
}int main()
{//error//auto f4 = [&, a](){//	//a++;//	b++;//	c++;//	d++;//	e++;//	f++;//	cout << a << b << c << d << e << endl;//};//f4();return 0;
}

三: Lambda表达式可以接受哪些参数?

 Lambda表达式可以接受不同类型的参数,具体取决于功能接口中声明的方法的参数类型。参数可以是基本类型、对象类型、函数式接口类型或泛型类型。Lambda表达式的参数列表可以为空,也可以有一个或多个参数。参数列表需要用圆括号括起来,多个参数之间用逗号分隔。当只有一个参数时,可以省略圆括号。Lambda表达式的参数可以在箭头符号(->)之前进行定义,并在表达式中使用。例如:(int a, int b) -> a + b 是接受两个整数参数并返回它们的和的Lambda表达式。总之,Lambda表达式提供了一种简洁的方式来传递行为作为参数,并且可以接受不同类型的参数。<span class="em">1</span><span class="em">2</span><span class="em">3</span>

四: Lambda表达式的返回类型是如何推导的?

Lambda表达式的返回类型是通过上下文推导得出的。根据Java语言规范,当Lambda表达式只有一条语句时,会自动推导返回类型。如果Lambda表达式有多条语句,则需要显式指定返回类型。 在Lambda表达式的语法中,返回类型通常是可以省略的,编译器会根据上下文自动推导出返回类型。 Lambda表达式的返回类型推导是通过invokedynamic指令实现的。

<span class="em">1</span><span class="em">2</span><span class="em">3</span>

Lambda表达式的底层

class Rate
{
public:Rate(double rate) : _rate(rate){}double operator()(double money, int year){return money * _rate * year;}private:double _rate;
};//lambda_uuid  
//uuid--Universally Unique Identifier,即通用唯一识别码。
class lambda_xxxx
{
};
int main()
{// 函数对象double rate = 0.49;Rate r1(rate);r1(10000, 2);// 仿函数lambda_uuid// lambda -> lambda_uuidauto r2 = [=](double monty, int year)->double{return monty*rate*year; };r2(10000, 2);auto r3 = [=](double monty, int year)->double{return monty*rate*year; };r3(10000, 2);return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

目标检测(Object Detection):Fast R-CNN,YOLO v3

目录 目标检测(Object Detection) R-CNN SPPNet Fast R-CNN YOLO v1 YOLO v2 YOLO v3 目标检测(Object Detection) 任务是计算机视觉中非常重要的基础问题&#xff0c;也是解决图像分割、目标跟踪、图像描述等问题的基础。目标检测是检测输入图像是否存在给定类别的物体…

适配器模式实现stack和queue

适配器模式实现stack和queue 什么是适配器模式&#xff1f;STL标准库中stack和queue的底层结构stack的模拟实现queue的模拟实现 什么是适配器模式&#xff1f; 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结)&#xff…

浅谈泛在电力物联网发展形态与技术挑战

安科瑞 华楠 摘 要&#xff1a;泛在电力物联网是当前智能电网发展的一个方向。首先&#xff0c;总结了泛在电力物联网的主要作用和价值体现&#xff1b;其次&#xff0c;从智能电网各个环节概述了物联网技术在电力领域的已有研究和应用基础&#xff1b;进而&#xff0c;构思并…

OpenAI Function calling

开篇 原文出处 最近 OpenAI 在 6 月 13 号发布了新 feature&#xff0c;主要针对模型进行了优化&#xff0c;提供了 function calling 的功能&#xff0c;该 feature 对于很多集成 OpenAI 的应用来说绝对是一个“神器”。 Prompt 的演进 如果初看 OpenAI 官网对function ca…

AI + Milvus:将时尚应用搭建进行到底

在上一篇文章中&#xff0c;我们学习了如何利用人工智能技术&#xff08;例如开源 AI 向量数据库 Milvus 和 Hugging Face 模型&#xff09;寻找与自己穿搭风格相似的明星。在这篇文章中&#xff0c;我们将进一步介绍如何通过对上篇文章中的项目代码稍作修改&#xff0c;获得更…

MySQL 日志

目录 一、日志概述 二、二进制日志 1、开启二进制日志 2、查看二进制文件 3、删除二进制日志文件 4、恢复二进制日志 5、暂时停止二进制日志功能 三、错误日志 1、启动和设置错误日志 2、查看错误日志 3、删除错误日志 四、通用查询日志 五、慢查询日志 一、日志概…

如何实现24/7客户服务自动化?建设智能客服知识库

客户自助服务是指用户通过企业或者第三方建立的网络平台或者终端&#xff0c;实现相关的自定义处理。实现客户服务自动化&#xff0c;对提高客户满意度、维持客户关系至关重要。客户服务自动化可以帮助企业以更快的速度和更高的效率来满足客户的售后服务要求&#xff0c;以进一…

红利期已过?2023跨境电商还吃香吗?亚马逊还能做吗?

2022年&#xff0c;由于疫情反复和外部因素的影响&#xff0c;跨境电商的情况并不乐观。但这并不意味着跨境电商已经走到了绝境。随着贸易全球化的深入发展&#xff0c;平台规则不断完善&#xff0c;国家相继出台最新的扶持政策&#xff0c;为跨境电商企业带来了更多的发展机遇…

1.1 VMware Workstation与Kali的安装和配置1

资源见专栏第一篇文章https://blog.csdn.net/algorithmyyds/article/details/132457258 安装VMware 不多加赘述&#xff0c;直接按顺序安装即可。 有以下需注意的地方&#xff1a; 1.建议选择增强型服务&#xff1b; 2.不要加入体验改进计划。是否开启提示更新看你的想法&…

Java数据结构学习和源码阅读(线性数据结构)

线性数据结构 链表 LinkList 链表的数据结构 一组由节点组成的数据结构&#xff0c;每个元素指向下一个元素&#xff0c;是线性序列。 最简单的链表结构&#xff1a; 数据指针&#xff08;存放执行下一个节点的指针&#xff09; 不适合的场景&#xff1a; 需要循环遍历将…

JVM及垃圾回收机制

文章目录 1、JVM组成&#xff1f;各部分作用&#xff1f;1.1 类加载器&#xff08;Class Loaders&#xff09;1.2 运行时数据区&#xff08;Runtime Data Area&#xff09;1.3 执行引擎&#xff08;Execution Engine&#xff09;1.4 本地方法接口&#xff08;Native Interface&…

C++二叉树进阶

本期内容我们讲解二叉树的进阶知识&#xff0c;没有看过之前内容的小伙伴建议先看往期内容 二叉树-----补充_KLZUQ的博客-CSDN博客 目录 二叉搜索树 代码实现 基础框架 Insert Find Erase 析构函数 拷贝构造 赋值 二叉搜索树的应用 全部代码 二叉搜索树 二叉搜索树…