C++:函数指针进阶(三):Lambda函数详解(二)

news2024/11/15 15:59:47

一:Lambda表达式概述

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

二:lambda表达式示例

Lambda有很多种叫法,有Lambda表达式,Lambda函数,匿名函数,本文为了方便表述统一用Lambda表达式叙述。下面是一个Lambda表达式实例。

#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));
          }
      // Lambda expression end
}
在上面的实例中,std::sort 函数第三个参数应该是传递一个 排序规则的函数,但是这个实例中直接将排序函数的 实现:写在了应该传递函数的位置,省去了定义排序函数的过程,对于这种不需要复用且短小的函数,直接传递函数体可以增加代码的可读性。

三:Lambda表达式语法定义

 

1:捕获列表:在C++规范中也称为Lambda导入器,捕获列表总是出现在lambda函数的开始处。实际上,[] 是lambda引出符,编译器根据该引出符判断接下来的代码是 lambda函数,捕获列表能够捕捉上下文的变量,以供Lambda函数使用。

2:参数列表:与普通函数的参数列表一致,如果不需要参数传递,则可以连同括号 “()” 一起省略

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

4:异常说明:用于lambda表达式内部函数抛出的异常。

5:返回类型:lambda表达式的函数体返回类型我们可以在不需要返回值得时候可以连同 “->”一起省略。此外,在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。

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

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

6:lambda函数体:与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。

 四:Lambda表达式的优缺点

优点

  1. 可以直接在需要调用函数的位置定义短小精悍的函数,而不需要预先定义好函数
  2. 使用lambda表达式变得更加紧凑,结构层次更加明显,代码可读性好

例如:

std::find_if(v.begin(),v.end(),[](int& item) {return item >2} ) ;

缺点:

  • lambda表达式语法比较灵活,增加了阅读代码的难度
  • 对于函数复用无能为力 

五:lambda表达式工作原理

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

auto  print  = [] {cout <<  " hello world" << endl ;  }

编译器会把上述代码翻译为下面代码

class print_class 
{

public:
    void operator()(void) const {
        
         cout << "hello world"  << endl;
    }

};


// 用构造的类创建对象,print 此时就是 一个函数对象
auto print = print_class();

事实上,编译器这么翻译和仿函数基本是一致的。

#include<iostream>
#include<string>

using namespace std;

class Functor
{
 public:
        void operator()(const string& str) const
        {

            cout<< str << endl;
        }
    
}

int main(){
    Functor myFunctor;
    myFunctor("hello");
    return 0;
}

 六: lambda表达式举例

6.1:lambda表达式被:函数指针,auto,  function等方式接收

#include<iostream>
#include<string>
#include<functional>
#include "lambda_.h"
using namespace std;

typedef void (*p_nameFunc)(string name);

void use_lambda1() {
	// 1:匿名调用
	[](string name) {
	
		cout << "this is anonymous" << endl;
		cout << "hello" << endl;
	}("jack ma");

	// 2:通过auto赋值
	auto fname = [](string name)->string {
		cout << "this is auto" << endl;
		cout << "hello" << endl;
		return "hello world";
	};
	fname("Robin ma");

	// 函数指针
	p_nameFunc fname2 = [](string name)
	{
		cout << "this is P_nameFunc" << endl;
		cout << "hello " << name << endl;
	};
	fname2("liu");

	// 4:function
	function<void(string)> funcName;
	funcName = [](string name)
	{
		cout << "this is function" << endl;
		cout << "hello " << name << endl;
	};
	funcName("wang");
}

int main() {

	use_lambda1();
}

 6.2:lambda捕获方式

void use_lambda2() {
	int age = 33;
	int score = 100;
	string name = "jack";
	string job = "softengineer";

	// 值捕获
	[age, name](string name_)
	{
		cout << "age is: " << age << "  name is: " << name << " self-name is: " << name_ << endl;
		//  name = "xiaoli"; // error : 表达式必须是可修饰的左值
		//  age = 20;  //  error : 表达式必须是可修饰的左值
	}("vivo");

	// 引用捕获
	[&age, &name](string name_)
	{
		cout << "age is: " << age << " name is : " << name << "self-name is: " << name_ << endl;
		name = "xiaoli";
		age = 20;
	}("huawei");

	// 全部用值捕获,name用应用捕获
	[=, &name]()
	{
		cout << "age is: " << age << " name is: " << name << " score is: " << score << " job is: " << job << endl;
		name = "cui hua";
	}();

	//  全部用引用捕获,只有name 用值捕获
	[&, name]()
	{
		cout << "age is: " << age << " name is: " << name << " score is: " << score << " job is: " << job << endl;
	}();
}

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

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

相关文章

记自己开发的淘宝客优惠券

目录 1.首页 1.1详情 1.2口令 1.3分类 1.4搜索 1.5个人中心 2.API开发教程 2.1什么是淘宝客 组成模式 2.2API申请 2.3SDK下载 2.3后台管理 闲暇时间浏览网站时&#xff0c;看到有关淘宝优惠券推广的文章&#xff0c;就想着能不能自己也做一个微信小程序。 但是&…

论文投稿指南——中文核心期刊推荐(化学 2)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

Java里一个线程调用了Thread.interrupt()到底意味着什么?

interrupted()是Java提供的一种中断机制&#xff0c;要把中断搞清楚&#xff0c;还是得先系统性了解下什么是中断机制。 什么是中断&#xff1f; 在Java中没有办法立即停止一条线程&#xff0c;然而停止线程却显得尤为重要&#xff0c;如取消一个耗时操作。因此&#xff0c;Ja…

zig语言代替C语言进行裸机开发的尝试-2023年笔记

接触rust的时候&#xff0c;无意中认识了zig&#xff0c;目前版本是zig 0.10.0&#xff0c;还没有正式的1.0版本。 初步使用的感受&#xff1a; 1). 用zig写出的代码更防崩&#xff0c;不会像C那样出现很多内存非法访问的情况 (比如这些情形&#xff1a;栈保护、整数溢出、…

pyqt5中QGraphicsView弹出菜单

QPainter与Graphics View 架构的区别PyQt5 提供了两种绘图方法。一种是使用 QPainter 类在 QWidget 类提供的画布上画图&#xff0c;可以 绘制点、线、圆等各种基本形状&#xff0c;从而组成自己需要的图形。所有界面组件都是 QWidget 的子类&#xff0c; 界面上的按钮、编辑框…

74、【哈希表】leetcode——18. 四数之和(C++版本)

题目描述 原题链接&#xff1a;18. 四数之和 解题思路 思路与三数之和&#xff1a;15. 三数之和&#xff0c;区别之处在于&#xff1a; 1、多一层for循环&#xff0c;用于多加一个数。 四数之和就是在三数之和多加一个数&#xff0c;用前两个数相加&#xff0c;后面两个数继…

Hadoop之MapReduce

一、概述 MapReduce 核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的 分布式运算程序&#xff0c;并发运行在一个 Hadoop 集群上。 1、优缺点&#xff1a;优点&#xff1a;1&#xff09;MapReduce 易于编程 它简单的实现一些接口&#xff0c;就可以完成一个…

(day2)自学java综合练习

目录 1.卖飞机票 2.找质数 3.开发验证码 4.数组元素的复制 5.评委打分 6.数字加密 7.数字解密 8.抢红包 9.模拟双色球 10.二维数组 1.卖飞机票 机票价格按照淡季旺季、头等舱和经济舱收费、输入机票原价、月份和头等舱或经济舱。按照如下规则计算机票价格&#xff1…

推荐两个好用的虚拟机、SSH 终端开源工具(Virtual Box、WindTerm)

笔者最近因一些变故&#xff0c;加上阳了&#xff0c;停更了一段时间&#xff0c;并提前回老家过年了。因并没有带笔记本电脑回去&#xff0c;故在折腾了一番老家电脑后&#xff0c;选择拥抱开源&#xff0c;使用一些开源的工具&#xff0c;而非习惯的 VMware Workstation 和 S…

Python3,区区10行代码,批量把图片插入Excel指定单元格中,省下时间去烫头发。

这里写目录标题1、引言2、代码实战2.1 代码示例2.2 遇到问题及处理方案2.2.1 遇到问题2.2.2 解决方案3、总结1、引言 小屌丝&#xff1a;鱼哥&#xff0c; 想请教你个问题。 小鱼&#xff1a;啥问题呢&#xff1f; 小屌丝&#xff1a;我想把图片插入到excel里面 小鱼&#xff…

AVS3变换之ISP和ISTS

ISP&#xff08;Implicit Selected Transform&#xff09;是AVS3中新增的针对intra块的变换工具&#xff0c;IST对intra块提供了两种可分离的变换核&#xff0c;编码器根据RDO选择最优的变换核&#xff0c;但是对于选中的变换核不在码流中传输其索引&#xff0c;而是将其索引隐…

今天给大家介绍一篇医院医疗管理系统的设计与实现(源码+论文)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

Java开发学习(三十七)----SpringBoot多环境配置及配置文件分类

一、多环境配置 在工作中&#xff0c;对于开发环境、测试环境、生产环境的配置肯定都不相同&#xff0c;比如我们开发阶段会在自己的电脑上安装 mysql &#xff0c;连接自己电脑上的 mysql 即可&#xff0c;但是项目开发完毕后要上线就需要该配置&#xff0c;将环境的配置改为…

亚马逊云科技 2022 re:Invent 的几个关键词:数据、云原生端到端、安全

一转眼&#xff0c;又是一年。2022 年云计算行业重要的技术趋势和方向里&#xff0c;亚马逊云科技一年一度的 re:Invent 大会是不可或缺的一环。 今年已经是 re:Invent 大会连续举办的第十一年&#xff0c;和往年一样&#xff0c;亚马逊云科技将一年的重磅技术观察和实践干货悉…

【数据结构】单链表 — 纯C实现单链表

目录&#x1f48c;前言一、定义1.概念2.特点3.优点4.缺点5.结点定义接口实现创建链表结点创建单个结点创建链表打印链表测试创建功能尾插尾删尾部插入尾部删除尾插尾删测试头插头删头部插入头部删除头插头删测试pos位的插入删除查找pos位置在pos位置前插入在pos位置后插入删除p…

CUDA和Compute Capability

Compute Capability 参考 指示GPU硬件能够支持的特性&#xff0c;可以被应用参考哪些特性可以运行。 这里能够找到不同Compute Capability对应的硬件特性。比如我的笔记本搭载了一块Geforce830m&#xff0c;Compute Capability为5.0&#xff0c;硬件特性为 另外有关技术细节比…

面试官问我HTTP,我真的是

面试官&#xff1a;今天要不来聊聊HTTP吧&#xff1f; 候选者&#xff1a;嗯&#xff0c;HTTP「协议」是客户端和服务器「交互」的一种通迅的格式 候选者&#xff1a;所谓的「协议」实际上就是双方约定好的「格式」&#xff0c;让双方都能看得懂的东西而已 候选者&#xff1…

2023-01-02 Echarts学习笔记(一) 基础概念和应用示例:折线图

文章目录0.什么是Echarts?1.常见使用场景2.使用Echarts的基本步骤3.应用示例:做一个折线图4.参考资料0.什么是Echarts? ECharts.js是 百度出品的一个开源 Javascript 数据可视化库 一个使用 JavaScript 实现的开源可视化库&#xff0c; 可以流畅的运行在 PC 和移动设备上&a…

【数据结构】二叉树递归算法代码总结

文章目录一、内容介绍二、算法总结2.1 二叉树结构2.2 完整代码2.3 输出结果三、Reference四、总结一、内容介绍 上一年备考数据结构中自己整理并验证过的二叉树递归算法。包括&#xff1a; 1、二叉树的创建&#xff1b; 2、二叉树的先、中、后序的递归遍历&#xff1b; 3、输出…

[项目说明]-基于人工智能博弈树,极大极小(Minimax)搜索算法并使用Alpha-Beta剪枝算法优化实现的可人机博弈的AI智能五子棋游戏。

个人选题项目 基于人工智能博弈树&#xff0c;极大极小(Minimax)搜索算法并使用Alpha-Beta剪枝算法优化实现的可人机博弈的AI智能五子棋游戏。 设计目标及主要内容 本系统是根据传统五子棋游戏的功能编写&#xff0c;其功能实现了基于AI人工智能算法实现智能的人机对弈五子棋…