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

news2024/11/15 2:11:09

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)

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

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

相关文章

linux系统如何安装nginx

首先下载nginx安装包 wget -c http://nginx.org/download/nginx-1.23.1.tar.gz然后解压安装包 tar -zxvf nginx-1.23.1.tar.gz如果服务器没有wget&#xff0c;可以安装一下&#xff0c;有的话可以跳过 yum install -y wget 然后安装相关依赖 yum install -y gcc-c zlib zl…

pdf.js使用步骤

使用pdfjs 网页在线预览需要后端服务器支持 1、下载PDF.js 源码包 地址&#xff1a;PDF.js 2、解压源码包&#xff0c;将源码包放置到后端服务器 3、后端部署完成后 访问 viewer.html 类似上图 4、访问在线pdf文件 http://localhost:8081/web/viewer.html?filexxxx.pdf …

超好用的自动化测试工具——Python脚本

前言 ⾃动化测试会越来越受到重视 在移动互联⽹时代&#xff0c;对于质量的要求⽐PC时代⾼的多&#xff0c;⽽投⼊产出⽐最⾼的⾃动化测试&#xff0c;将会是⼤部分公司的⾸选⽅向&#xff0c;但需要严格掌握⼀门语⾔。 快速、高效的测试工具及脚本&#xff0c;能使程序猿的…

Docker技术概论(4):Docker CLI 基本用法解析

Docker技术概论&#xff08;4&#xff09; Docker CLI 基本用法解析 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:http…

2024腾讯云服务器优惠价格表又降价了,给同行干emo了

腾讯云优惠活动2024新春采购节活动上线&#xff0c;云服务器价格已经出来了&#xff0c;云服务器61元一年起&#xff0c;配置和价格基本上和上个月没什么变化&#xff0c;但是新增了8888元代金券和会员续费优惠&#xff0c;腾讯云百科txybk.com整理腾讯云最新优惠活动云服务器配…

C++条件变量

概述 条件变量的使用&#xff0c;其实是一种多线程通知模式&#xff0c;当线程一使用完数据后&#xff0c;通过条件变量通知其他线程&#xff0c;C11后开始支持。 说明 条件变量必须配合mutex使用&#xff0c;确保并发访问的排他性 std::unique_lock<std::mutex> loc…

文献笔记:LINE: Large-scale Information Network Embedding

paper 看完√ code复现ing https://arxiv.org/pdf/1503.03578v1.pdf 本文研究了将非常大的信息网络嵌入到低维向量空间的问题&#xff0c;这在可视化、节点分类和链路预测等许多任务中都很有用。大多数现有的图形嵌入方法无法扩展到通常包含数百万个节点的现实世界信息网络。…

【C语言】指针初阶2.0版本

这篇博文我们来继续学习指针的其他内容 指针2.0 传值调用与传址调用传值调用传址调用 一维数组与指针理解数组名使用指针深入理解一维数组 二级指针指针数组二维数组与指针 传值调用与传址调用 在开始之前&#xff0c;我们需要先了解这个概念&#xff0c;后面才能够正常的学习…

成功解决‘OpenpyxlWriter’ object has no attribute ‘save’

成功解决‘OpenpyxlWriter’ object has no attribute ‘save’ &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到…

在vue2中使用饼状图

1.引入vue2和echarts <script src"https://cdn.jsdelivr.net/npm/vue2.7.14/dist/vue.js"></script> <script src"https://cdn.jsdelivr.net/npm/echarts5.4.0/dist/echarts.min.js"></script> 2.1 补充基本的body内容 <div id…

在UniApp中引入大于40kb字体包的记录

因为项目UI需要特殊字体&#xff0c;所以给了一个80kb字体包&#xff0c;但是在正常的使用导入时候发现不生效 这是我的导入过程 1.把下载好的文件放入static/font目录中 2.在app.vue中引用 font-face { font-family: zitiming; src: url(/static/font/YouSheBiaoTiHei-2.t…

C++ //练习10.3 用accumulate求一个vector<int>中的元素之和。

C Primer&#xff08;第5版&#xff09; 练习 10.3 练习10.3 用accumulate求一个vector中的元素之和。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /*******************************************************************…

【Pytorch】成功解决AttributeError: ‘tuple’ object has no attribute ‘dim’

【Pytorch】成功解决AttributeError: ‘tuple’ object has no attribute ‘dim’ &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&…

HTML---表单验证

文章目录 目录 本章目标 一.表单验证概述 二.表单选择器 属性过滤选择器 三.表单验证 表单验证的方法 总结 本章目标 掌握String对象的用法会使用表单选择器的选择页面元素会使用JQuery事件进行表单验证Ajax的概念和作用 一.表单验证概述 前端中的表单验证是在用户提交表…

《Spring Security 简易速速上手小册》第5章 高级认证技术(2024 最新版)

文章目录 5.1 OAuth2 和 OpenID Connect5.1.1 基础知识详解OAuth2OpenID Connect结合 OAuth2 和 OIDC 5.1.2 重点案例&#xff1a;使用 OAuth2 和 OpenID Connect 实现社交登录案例 Demo 5.1.3 拓展案例 1&#xff1a;访问受保护资源案例 Demo测试访问受保护资源 5.1.4 拓展案例…

HCIA-Datacom实验指导手册:7 构建简单 IPv6 网络

HCIA-Datacom实验指导手册&#xff1a;7 构建简单 IPv6 网络 一、实验介绍&#xff1a;二、实验拓扑&#xff1a;三、实验目的&#xff1a;四、配置步骤&#xff1a;步骤 1 设备基础配置设备命名 步骤 2 配置设备及接口 IPv6 功能步骤 3 配置接口的 link-local 地址&#xff0c…

c++数据结构算法复习基础-- 2 -- 线性表-单链表-常用操作接口-复杂度分析

1、链表 特点 每一个节点都是在堆内存上独立new出来的&#xff0c; 节点内存不连续优点 内存利用率高&#xff0c;不需要大块连续内存 插入和删除节点不需要移动其它节点&#xff0c;时间复杂度O(1)。 不需要专门进行扩容操作缺点 内存占用量大&#xff0c;每一个节点多出存…

使用 MongoDB Atlas 无服务器实例更高效地开发应用程序

使用 MongoDB Atlas无服务器实例更高效地开发应用程序 身为开发者&#xff0c;数据库并不一定需要您来操心。您可不想耗费时间来预配置集群或调整集群大小。同样地&#xff0c;您也不想操心因未能正确扩展而导致经费超标。 MongoDB Atlas 可为您提供多个数据库部署选项。虽然…

操作系统开篇

目录 一. 预备知识二. 操作系统的功能和目标2.1. 系统资源的管理者2.2 向上层提供方便易用的服务2.3 最接近硬件的软件 三. 操作系统的四个特征3.1 并发性3.2 共享性3.3 虚拟性3.4 异步性 四. 操作系统的发展与分类 \quad 一. 预备知识 \quad 计算机结构原理&#xff08;Intel …

《PyTorch深度学习实践》第十三讲RNN进阶

一、 双向循环神经网络&#xff08;Bidirectional Recurrent Neural Network&#xff0c;BiRNN&#xff09;是一种常见的循环神经网络结构。与传统的循环神经网络只考虑历史时刻的信息不同&#xff0c;双向循环神经网络不仅考虑历史时刻的信息&#xff0c;还考虑未来时刻的信息…