c++中使用lambda表达式的作用和用法

lambda表达式

这是C++11引入的一种新特性,它可以让您在需要定义函数对象的地方,直接编写一个匿名的、可以捕获上下文变量的函数体,非常适合用作回调函数、临时计算或定义小型函数对象。

lambda表达式与普通函数类似,也有参数列表、返回值类型和函数体,只是它的定义方式更简洁,并且可以在函数内部定义。

lambda表达式的语法

lambda表达式的一般形式如下:

[capture] (parameters) mutable -> return-type { body }

其中:

  • [capture]捕获列表,表示lambda表达式可以捕获哪些上下文中的变量,以值或引用的方式。捕获列表可以为空,表示不捕获任何变量,也可以使用 = & 表示按值或引用捕获所有变量,还可以指定具体的变量名,用逗号分隔。例如:
[a, &b] // 按值捕获a,按引用捕获b
[=, &c] // 按值捕获所有变量,但按引用捕获c
[&] // 按引用捕获所有变量
[this] // 捕获当前的this指针
  • (parameters)参数列表,表示lambda表达式可以接受哪些参数,与普通函数的参数列表相同。参数列表可以为空,表示不接受任何参数,也可以使用auto来推断参数类型。例如:
() // 不接受任何参数
(int x, double y) // 接受两个参数,类型分别为int和double
(auto x, auto y) // 接受两个参数,类型由编译器推断
  • mutable修饰符,表示lambda表达式的函数体可以修改按值捕获的变量,否则默认是常量。如果使用了mutable,则参数列表不能省略。例如:

    [x] () mutable { x++; } // 可以修改按值捕获的x
    [x] () { x++; } // 错误,不能修改常量x
    
  • -> return-type返回值类型,表示lambda表达式的返回值的类型,与普通函数的返回值类型相同。返回值类型可以省略,由编译器根据函数体的返回语句推断。例如:

    () -> int { return 42; } // 返回值类型为int
    () { return 42; } // 返回值类型由编译器推断为int
    
  • { body }函数体,表示lambda表达式的具体逻辑,与普通函数的函数体相同。函数体可以使用捕获列表和参数列表中的变量,也可以调用其他函数或lambda表达式。例如:

    [a] (int x) { return a + x; } // 函数体返回a和x的和
    [] { std::cout << "Hello" << std::endl; } // 函数体打印一句话
    

lambda表达式的使用

lambda表达式的使用方法是在定义的地方加上一对圆括号,表示调用该lambda表达式,括号中可以传递参数,也可以为空。lambda表达式的返回值可以赋值给一个变量,也可以作为另一个函数的参数或返回值。lambda表达式的使用场景有很多,

举例:

当不使用 lambda表达式时代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>

// Define a function to print an integer
void print_int(int x) {
    std::cout << x <<",";
}

// Define a function object to compare two integers by their absolute values
struct abs_compare {
    bool operator()(int x, int y) {
        return std::abs(x) > std::abs(y);
    }
};

int main() {
    std::vector<int> v1 = {1, -12, 3, -4, 5,6,7,-9};
    // Use the print_int function as the third argument of std::for_each
    std::for_each(v1.begin(), v1.end(), print_int);
    std::cout << std::endl;
    // Use the abs_compare function object as the third argument of std::sort
    std::sort(v1.begin(), v1.end(), abs_compare());
    // Use the print_int function again
    std::for_each(v1.begin(), v1.end(), print_int);
    return 0;
}

 

当使用 lambda表达式时的代码:

#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
    std::vector<int> v1 = {1, -12, 3, -4, 5,6,7,-9};
    // Use brackets around the lambda expression
    std::for_each(v1.begin(),v1.end(),  [] (const int& x){std::cout<<x<<",";});
    std::cout<<std::endl;
    // Use braces around the lambda body
    std::sort(v1.begin(),v1.end(),    [] (const int& x,const int& y){return abs(x) > abs(y);});
    std::for_each(v1.begin(),v1.end(),[](const int &x){std::cout<<x<<",";});
    return 0;
}

例如:

  • 作为回调函数,例如在STL的算法中,可以使用lambda表达式来自定义比较函数、谓词函数、操作函数等。例如:

    std::vector<int> v{1, 2, 3, 4, 5};
    // 使用lambda表达式作为比较函数,按照绝对值降序排序
    std::sort(v.begin(), v.end(), 
                 [] (const int &x,const int &y) { return abs(x) > abs(y); });
    // 使用lambda表达式作为谓词函数,查找第一个偶数
    auto it = std::find_if(v.begin(), v.end(),
                 [] (const int &x) { return x % 2 == 0; });
    // 使用lambda表达式作为操作函数,对每个元素加一
    std::for_each(v.begin(), v.end(), 
                 [] (const int &x)  { x++; });
    
  • 作为临时计算,例如在需要一个简单的计算结果时,可以使用lambda表达式来封装计算逻辑,而不需要定义一个单独的函数。

例如:使用lambda表达式计算两个数的最大公约数

// 定义一个lambda表达式,接受两个参数a和b,返回它们的最大公约数
auto gcd = [] (int a, int b) -> int {
    if (b == 0) return a;
    else return gcd(b, a % b);
};

// 调用lambda表达式,传入24和36
int result = gcd(24, 36);

// 输出结果
std::cout << "最大公约数是:" << result << std::endl;
  • 作为小型函数对象,例如在需要一个简单的函数对象时,可以使用lambda表达式来定义一个匿名的函数对象,而不需要定义一个单独的类或结构体。

例如:使用lambda表达式定义一个函数对象,用于计算两个数的和

auto adder = [](const int &x,const int &y) { return x + y; };
std::cout << adder(1, 2) << std::endl; // 输出3

参考链接:

C++ Lambda表达式的完整介绍 - 知乎 (zhihu.com)

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

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

相关文章

[MYSQL数据库]--mysql的基础知识

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、数据库…

上门废品回收小程序开发,从传统到线上,到“高收益”

随着我国社会经济不断发展&#xff0c;人们的消费水平能力也在不断提升&#xff0c;日常生活中会产生非常多的废弃物品&#xff0c;为废品回收行业带来了大量的机遇。在回收行业的发展前景下&#xff0c;也为年轻人带来了创业机会&#xff0c;既获得利润&#xff0c;也能为社会…

六、OpenAI之嵌入式(Embedding)

嵌入模式 学习怎么将文本转换成数字&#xff0c;解锁搜索等案例。 新的嵌入模型 text-embedding-3-small 和 text-embedding-3-large&#xff0c;是目前最新的并且性能最好的嵌入模型&#xff0c;成本低&#xff0c;支持多语言&#xff0c;拥有控制所有大小的新参数 1. 什么是…

周鸿祎免费课演示AI新品,瞬时流量暴增现场增加服务器

2月29日&#xff0c;360创始人周鸿祎首堂AI免费课开讲&#xff0c;吸引千万网友围观。演讲现场周鸿祎演示了两款AI驱动的新产品。在演示测试版360AI搜索时&#xff0c;由于用户体验火爆&#xff0c;瞬时流量暴增44倍&#xff0c;为满足用户和全网用户需求临时增加了服务器。产品…

solidity编程

一.Solidity 简介 Solidity 是⼀种⽤于编写以太坊虚拟机&#xff08; EVM &#xff09;智能合约的 编程语⾔。我认为掌握 Solidity 是参与链上项⽬的必备技 能&#xff1a;区块链项⽬⼤部分是开源的&#xff0c;如果你能读懂代码&#xff0c;就可以 规避很多亏钱项⽬。…

LeetCode 2265.统计值等于子树平均值的节点数

给你一棵二叉树的根节点 root &#xff0c;找出并返回满足要求的节点数&#xff0c;要求节点的值等于其 子树 中值的 平均值 。 注意&#xff1a; n 个元素的平均值可以由 n 个元素 求和 然后再除以 n &#xff0c;并 向下舍入 到最近的整数。 root 的 子树 由 root 和它的所…

大模型量化技术原理-ZeroQuant系列

近年来&#xff0c;随着Transformer、MOE架构的提出&#xff0c;使得深度学习模型轻松突破上万亿规模参数&#xff0c;从而导致模型变得越来越大&#xff0c;因此&#xff0c;我们需要一些大模型压缩技术来降低模型部署的成本&#xff0c;并提升模型的推理性能。 模型压缩主要分…

什么是VR紧急情况模拟|消防应急虚拟展馆|VR游戏体验馆加盟

VR紧急情况模拟是利用虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;技术来模拟各种紧急情况和应急场景的训练和演练。通过VR技术&#xff0c;用户可以身临其境地体验各种紧急情况&#xff0c;如火灾、地震、交通事故等&#xff0c;以及应对这些紧急情况的…

IM(即时通讯-聊天工具):一文读懂,技术栈和界面设计。

大家好&#xff0c;我是贝格前端工场&#xff0c;本期继续分享IM&#xff08;即时通讯&#xff09;的设计&#xff0c;欢迎大家关注&#xff0c;如有B端写系统界面的设计和前端需求&#xff0c;可以联络我们。 一、什么是IM&#xff08;聊天工具) IM即时通讯工具是指一类用于…

C++——类和对象(2):构造函数、析构函数、拷贝构造函数

2. 类的6个默认成员函数 我们将什么成员都没有的类称为空类&#xff0c;但是空类中并不是什么都没有。任何类中都会存在6个默认成员函数&#xff0c;这6个默认成员函数如果用户没有实现&#xff0c;则会由编译器默认生成。 6个默认成员函数包括&#xff1a;负责初始化工作的构造…

怎么调用文心一言的api接口生成一个简单的聊天机器人(python代码)

寒假在学习大模型&#xff0c;但也没弄出多少眉目&#xff0c;电脑性能还有点小问题&#xff0c;大模型总跑不起来&#xff0c;只会简单调用一下现有的大模型的接口&#xff0c;例如&#xff1a;文心一言&#xff0c;下面展示一下代码&#xff1a; import tkinter as tk impor…

Linux中如何在创建子线程的时候设置为分离属性

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<unistd.h> #include <pthread.h> void *mythread(void *arg) {printf("id[%ld]\n",pthread_self()); } int main() { //定义pthread_…

力扣550 游戏玩法分析 IV

目录 题目描述 思路整理 1. 首次登录日期 2. 第二天登录 3. 计算比率 实现思路 完整代码及解释 题目描述 Table: Activity ----------------------- | Column Name | Type | ----------------------- | player_id | int | | device_id | int | | ev…

华为自动驾驶技术详解报告分享

ADS2.0首发搭载问界M5智驾版&#xff0c;城市NCA计划年底全国开通。2023年4月16日华为在智能汽车解决方案发布会上发布了最新的ADS2.0产品&#xff0c;硬件数量减少至27个(11个摄像头12个超声波雷达3个毫米波雷达1个激光雷达,ADS1.0有34个)&#xff0c;车载计算平台改为MDC610&…

苹果ios群控软件开发常用源代码分享!

在移动软件开发领域&#xff0c;苹果设备由于其封闭性和安全性受到了广大开发者的青睐&#xff0c;然而&#xff0c;这也为开发者带来了一些挑战&#xff0c;特别是在进行群控软件开发时。 群控软件是指可以同时控制多台设备的软件&#xff0c;这在自动化测试、批量操作等场景…

网络编程难点之select、poll与epoll详解

前言 为什么需要I/O多路复用技术&#xff1f; 首先&#xff0c;I/O多路复用技术主要被应用在需要高性能的网络服务器程序中。 高性能网络服务器程序需要做的事情就是供多个客户端同时进行连接并处理客户端传送过来的数据请求&#xff1a; 对于这种情况&#xff0c;很多人自然…

二叉树——二叉树所有路径

二叉树所有路径 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,null,5] 输出&#xff1a;["1->2->5","1-…

leetcode刷题日记-合并N个升序链表

题目描述 解题思路 相信大家都做过两个有序链表合并的习题吧。该题的解决思路是建立在两个有序链表合并的基础上。使用的方法是递归。 两个有序链表合并思路 1.如果其中一个链表为空&#xff0c;直接返回另一个链表&#xff0c;因为一个空链表和非空链表的合并结果就是非空链…

在微服务整合dubbo,以为微服务版的若依为例

在微服务整合dubbo&#xff0c;以为微服务版的若依为例 一、环境二、整合过程1、父模块依赖2、生产者3、消费者 三、修改若依的服务调用方式为dubbo1、改造系统模块2、改造认证授权中心 四、整合过程遇到的问题1、出现循环引用2、出现依赖冲突3、启动出现端口号被占用4、出现某…

windows U盘不能识别

windows U盘不能识别 1、问题描述2、问题分析解决3、把U盘插到windows电脑上试试能不能识别 1、问题描述 windwos u盘不能识别 u盘被拿到mac电脑上做了启动盘之后&#xff0c;就不能被windows识别了。题主很奇怪里面被mac电脑的同学放了什么&#xff0c;因此想到把优盘挂载到L…