【C++11入门】新特性总结之lambda表达式

news2024/10/17 7:51:44

现代C++语言的核心特征之一:lambda表达式。虽然其它编程语言早已具备了这种特性,但直到C++11标准发布,C++11才具备了lambda表达式。本节主要讲解lambda表达式的语法和使用方法。具体包括:捕获列表、可选参数列表、可选异常说明符、可选返回值类型等。此外,还将介绍lambda表达式在STL算法中的应用和泛型lambda表达式的使用方法。

函数对象:

不过在此之前我们先来了解一下函数对象(仿函数)。函数对象其实就是在类内对函数调用运算符:()进行重载。因为使用方法与函数类似,我们又将其称为仿函数。

struct MyAdd{
public:
    int operator()(int a,int b){
        return a+b;
    }
};
class MyCompare{
public:
    bool operator()(int a,int b){
        return a<b;
    }
};

写两端的目的是为了告诉大家,C++中的struct和class都可以重载运算符来进行运算,一般我们又将返回值为bool的函数对象称为谓词,参数为一个就是一元谓词,参数为两个就是二元谓词

 那么我们知道函数对象又称仿函数,那么使用方法我们就可以猜出来了:

void test01(){
    MyAdd add;
    cout<<add(1,3)<<endl;//输出4
}
void test02(){
    MyCompare compare;
    cout<<compare(2,5)<<endl;//true--实际输出1
}

仿函数是C++中用于实现功能对象的两种重要机制之一,另一个就是lambda表达式。C++中的lambda表达式的底层与仿函数类似。lambda表达式可以定义匿名函数。优点在于简洁、可以捕获作用域中的变量,使得可以在函数内部使用外部变量。


基本语法:

[capture](parameters) -> return_type { body }

基本的lambda表达式的语法如上。其中:

capture:捕获外部变量的方式。

parameters:匿名函数的参数列表。

return_type:返回类型,通常可以省略,编译器会进行推导。

body:lambda表达式的函数体。 

捕获列表:

捕获列表指定了lambda表达式可访问的变量,并包括以下几种方式:

值捕获:复制外部变量的值到lambda中。

int x=10;
auto lambda = [x](){return x+5;}; //用值传递

引用捕获:捕获外部变量的引用,可以在lambda中修改变量。 

int x = 10;  
auto lambda = [&x]() { x += 5; }; // x 通过引用捕获

 默认捕获:[=]:值捕获所有外部变量,[&]:引用捕获所有外部变量。

int a = 5, b = 10;  
auto lambda = [=]() { return a + b; }; // 所有变量以值捕获
auto lambda = [&]() { return a + b; }; // 所有变量以引用捕获

 混合捕获:可以混合使用值和引用捕获。

int x = 1, y = 2;  
auto lambda = [x, &y]() { return x + y++; }; // x 值捕获,y 引用捕获

在这里大家肯定有点疑惑,捕获列表的用途是什么, 这有什么用,还没有看明白。这里我举个例子:

int main(){

    int a=10,b=20,c=30;
    char ch1='a',ch2=’B‘;
    //然后我想让ch1=a+b+c;但是过了本行不影响ch1的值
    return 0;
}

我想通过函数的方式调用,有很多方式,但大都是外部定义一个函数,但这时候,我们需要传入参数,变量多的时候,我们还要传很多的参数,定义普通的函数显然有点不合适。那么lambda表达式就很合适了,直接捕获所有变量,然后想使用啥使用啥,我眼中的lambda表达式其实是一种函数内部的匿名函数。 

参数和返回值:

参数:参数可以为空,也可以包含一个或多个参数,就像普通函数一样。

auto lambda = [](int a, int b) { return a + b; };

返回类型:如果返回类型明确、显式,可以调用->来指明返回类型,如果省略,编译器会自行推导。

底层探究: 

但凡是个表达式,都有其类型,那么lambda表达式是个什么类型呢?我们使用typeid().name()来输出一下看看。

这时候我们可以看出来lambda表达式的类型本身是一个类类型。每创立一个表达式,都会创建一个类,而且是在函数内部的作用域下创建的类,我们也可以看出来,每个lambda的类型都是不一样的。这时候我们想到了仿函数,仿函数是在类内重载了()运算符,那这个lambda表达式到底与仿函数有什么渊源呢?

 通过观察上面的反汇编语言。我们可以看出来,lambda的底层机制还是仿函数。只不过编译器会自动为你的lambda表达式生成一个类,将lambda表达式当作函数使用时其实就是调用类内的()重载函数。

STL算法应用:

Lambda 表达式经常与标准模板库(STL)的算法结合使用:

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

int main() {  
    std::vector<int> vec = {1, 2, 3, 4, 5};  
    std::for_each(vec.begin(), vec.end(), [](int &n) { n *= 2; });  
    //这里我们可以使用仿函数,也可以使用函数指针,也可以像本例一样使用lambda表达式
    for (const auto &n : vec) {  
        std::cout << n << " "; // 输出: 2 4 6 8 10  
    }  
    return 0;  
}
  • 简洁性: 不需要定义完整的函数,提高了代码的可读性。
  • 访问外部作用域: 可以直接使用外部的变量,而无需将其作为参数传递。
  • 灵活性: 可以在需要时快速定义函数,特别适用于 STL 算法。

注意事项:

  • Lambda 表达式在多线程环境下使用时要注意捕获对象的生命周期。
  • 当捕获的对象超出了作用域或被销毁后,如果 Lambda 仍然存在并使用这些对象,会导致未定义行为。

感谢大家!

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

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

相关文章

5分钟精通Windows环境变量

科普内容 what why how&#xff08;WWH&#xff09;三步走 1. what&#xff1a;Windows环境变量是什么 Windows环境变量&#xff0c;本质上是告诉了Windows操作系统一堆文件夹路径&#xff0c;如下图 2. why&#xff1a; 创造Windows环境变量的目的 发明Windows环境变量是为了…

多机编队—(3)Fast_planner无人机模型替换为Turtlebot3模型实现无地图的轨迹规划

文章目录 前言一、模型替换二、Riz可视化三、坐标变换四、轨迹规划最后 前言 前段时间已经成功将Fast_planner配置到ubuntu机器人中&#xff0c;这段时间将Fast_planner中的无人机模型替换为了Turtlebot3_waffle模型&#xff0c;机器人识别到环境中的三维障碍物信息&#xff0…

HarmonyOS开发(ArkUI简单使用)

一、开发准备 1.官网 https://developer.huawei.com/consumer/cn/ 2.工具 DevEco Studio 下载&#xff1a; 下载中心 | 华为开发者联盟-HarmonyOS开发者官网&#xff0c;共建鸿蒙生态 3.安装 4.开发组件ArkTs ArkTS是HarmonyOS主力应用开发语言。它在TypeScript&#xf…

分享一个关于产线工控安全的主机加固方案

在数字化时代&#xff0c;数据安全是企业运营的重中之重。勒索病毒作为一种新型的网络攻击手段&#xff0c;已经成为全球范围内企业面临的严峻挑战。最近&#xff0c;一起震惊全球的勒索病毒事件再次敲响了警钟&#xff1a;一家国际航运巨头遭受了勒索软件攻击&#xff0c;导致…

设计模式和软件框架的关系

设计模式和软件框架在软件开发中都有助于解决复杂问题和提高代码质量&#xff0c;但它们在概念和使用上存在一些区别。它们的关系可以通过以下几点理解&#xff1a; 层次与抽象程度 设计模式&#xff08;Design Patterns&#xff09;是一组通用的、可复用的解决方案&#xff0…

Android10 recent键相关总结

目录 初始化流程 点击Recent键流程 RecentsActivity 显示流程 RecentsModel 获取数据管理类 RecentsActivity 布局 已处于Recent界面时 点击recent 空白区域 点击返回键 recent组件配置 Android10 Recent 功能由 System UI&#xff0c;Launcher共同实现。 初始化流程 …

注册_登录安全分析报告:宝马中国

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

前端开发攻略---取消已经发出但是还未响应的网络请求

目录 注意&#xff1a; 1、Axios实现 2、Fetch实现 3、XHR实现 注意&#xff1a; 当请求被取消时&#xff0c;只会本地停止处理此次请求&#xff0c;服务器仍然可能已经接收到了并处理了该请求。开发时应当及时和后端进行友好沟通。 1、Axios实现 <!DOCTYPE html> &…

Map 双列集合根接口 HashMap TreeMap

Map接口是一种双列集合,它的每一个元素都包含一个键对象Key和值Value 键和值直接存在一种对应关系 称为映射 从Map集中中访问元素, 只要指定了Key 就是找到对应的Value 常用方法 HashMap实现类无重复键无序 它是Map 接口的一个实现类,用于存储键值映射关系,并且HashMap 集合没…

51单片机快速入门之 LED点阵 结合74hc595 的应用 2024/10/16

51单片机快速入门之 LED点阵 结合74hc595 的应用 74HC595是一种常用的数字电路芯片&#xff0c;具有串行输入并行输出的功能。它主要由两个部分组成&#xff1a;一个8位的移位寄存器和一个8位的存储寄存器。数据通过串行输入管脚&#xff08;DS&#xff09;逐位输入&#xff0…

unity Gpu优化

不一样的视角&#xff0c;深度解读unity性能优化。unity性能优化&#xff0c;unity内存优化&#xff0c;cpu优化&#xff0c;gpu优化&#xff0c;资源优化&#xff0c;资源包、资源去重优化&#xff0c;ugui优化。 gpu优化静态批处理静态批处理原理规则静态合批的原理静态合批的…

Spring Boot视频网站:安全与可扩展性设计

4 系统设计 4.1系统概要设计 视频网站系统并没有使用C/S结构&#xff0c;而是基于网络浏览器的方式去访问服务器&#xff0c;进而获取需要的数据信息&#xff0c;这种依靠浏览器进行数据访问的模式就是现在用得比较广泛的适用于广域网并且没有网速限制要求的B/S结构&#xff0c…

Appium环境搭建、Appium连接真机

文章目录 一、安装Android SDK二、安装Appium-desktop三、安装Appium Inspector 一、安装Android SDK 首先需要安装jdk&#xff0c;这里就不演示安装jdk的过程了 SDK下载地址&#xff1a;Android SDK 下载 1、点击 Android SDK 下载 -> SKD Tools 2、选择对应的版本进行下…

mysql 慢查询日志slowlog

慢查询参数 slow log 输出示例 # Time: 2024-08-08T22:39:12.80425308:00 #查询结束时间戳 # UserHost: root[root] localhost [] Id: 83 # Query_time: 2.331306 Lock_time: 0.000003 Rows_sent: 9762500 Rows_examined: 6250 SET timestamp1723127950; select *…

云栖实录 | 智能运维年度重磅发布及大模型实践解读

本文根据2024云栖大会实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a; 钟炯恩 | 阿里云智能集团运维专家 张颖莹 | 阿里云智能集团算法专家 活动&#xff1a; 2024 云栖大会 AI 可观测专场 -智能运维&#xff1a;云原生大规模集群GitOps实践 2024 …

【c++】c++11多线程开发

2 C多线程 本文是参考爱编程的大丙c多线程部分内容&#xff0c;按照自己的理解对其进行整理的一篇学习笔记&#xff0c;具体一些APi的详细说明请参考大丙老师教程。 代码性能的问题主要包括两部分的内容&#xff0c;一个是前面提到资源的获取和释放&#xff0c;另外一个就是多…

使用rabbitmq-operator在k8s集群上部署rabbitmq实例

文章目录 前言一、rabbitmq-operator二、进行部署1.部署cluster-operator2.创建自己需要的特定命名空间3.创建rabbitmq的instance4.创建nodeport访问 结果验证 前言 使用rabbitmq-operator在k8s集群上部署rabbitmq实例。时区设置为上海 一、rabbitmq-operator 官网地址&#…

数学建模算法与应用 第16章 优化与模拟方法

目录 16.1 线性规划 Matlab代码示例&#xff1a;线性规划求解 16.2 整数规划 Matlab代码示例&#xff1a;整数规划求解 16.3 非线性规划 Matlab代码示例&#xff1a;非线性规划求解 16.4 蒙特卡洛模拟 Matlab代码示例&#xff1a;蒙特卡洛模拟计算圆周率 习题 16 总结…

java代码生成器集成dubbo,springcloud详解以及微服务遐想

摘要 今天终于有了点空闲时间&#xff0c;所以更新了一下代码生成器&#xff0c;修复了用户反馈的bug&#xff0c;本次更新主要增加了dubbo和springcloud脚手架的下载功能&#xff0c;架子是本人亲自搭建&#xff0c;方便自由扩展或者小白学习使用&#xff0c;你也许会问为什么…

红日安全vulnstack (二)

目录 环境搭建 网卡设置 修改Kali网段 IP 分布 WEB渗透 Weblogin服务开启 漏洞扫描 CVE工具利用 MSF上线 内网渗透 域内信息收集 凭证横向移动 权限维持 黄金票据 参考文章 https://www.cnblogs.com/bktown/p/16904232.htmlhttps://blog.csdn.net/m0_75178803/ar…