[C++11] Lambda表达式完整解析

news/2024/4/24 5:05:39/

说明:C++11中的Lambda表达式是一种允许创建匿名函数对象的语法结构。Lambda表达式可以捕获作用域中的变量,并且可以像普通函数一样被调用。它们是C++11标准中引入的一个重要特性,旨在提供一种方便的方式来定义内联的小型函数,特别适用于编写回调函数、线程任务、以及与STL算法结合使用的场景。

Lambda表达式的基本语法如下:

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

其中概念解读如下:

  • 捕获列表:定义了Lambda表达式可以访问的外部变量。可以捕获值、引用或不捕获(默认情况下,Lambda不能访问外部变量)。
  • 参数列表:与普通函数的参数列表类似,可以有或没有参数,参数列表也可以省略。
  • 返回类型:Lambda表达式的返回类型可以显式指定,也可以由编译器根据函数体自动推导。
  • 函数体:包含Lambda表达式的代码实现。

在使用Lambda表达式前我们先了解下为什么引入Lambda表达式。知其然知其所以然。

1 C++11 为什么引入Lambda表达式?

C++11引入Lambda表达式的目的是为了提供一种方便、灵活且表达性强的方式来定义匿名函数。Lambda表达式的引入主要是基于以下几个原因和目标:

  • 代码封装和复用:Lambda表达式允许在代码中直接定义函数对象,这有助于封装一小段相关的代码,使得代码更加模块化。这种方式可以减少额外的函数定义,避免全局函数的污染,并且使得相关功能更加紧凑和易于复用。
  • 简洁性:在C++11之前,如果需要传递一个函数作为参数或者在循环中使用一个临时的函数对象,程序员通常需要定义一个命名的函数或者使用函数指针。Lambda表达式提供了一种更加简洁的方式来创建这些临时的函数对象,从而简化了代码。
  • 捕获上下文:Lambda表达式可以捕获其创建时周围的变量,这使得Lambda表达式可以访问定义它的函数的局部变量。这种特性非常有用,尤其是在需要使用到这些局部变量的回调函数或者模板函数中。
  • 支持函数式编程范式:Lambda表达式是函数式编程范式的一个重要组成部分。通过引入Lambda表达式,C++开始支持更多的函数式编程技术,如高阶函数、闭包等,这为程序员提供了更多的编程选择和灵活性。
  • 与STL和算法结合:STL(Standard Template Library)是C++的一个重要组成部分,它提供了一系列模板化的容器和算法。Lambda表达式可以非常方便地与STL算法结合使用,作为算法的参数传递,从而实现各种复杂的操作,如过滤、转换、查找等。
  • 增强表达力:Lambda表达式增强了C++的表达力,使得一些原本需要复杂模板元编程或宏定义的功能,现在可以用更加直观和易于理解的方式来实现。
  • 适应多核和并行计算:随着多核和多线程计算的普及,Lambda表达式提供了一种方便的方式来定义并行任务。结合C++11的线程库和其他并行编程库,Lambda表达式可以轻松地在多线程环境中使用。
  • 与现代C++开发相适应:随着C++语言的发展,现代C++开发趋向于更加简洁、模块化和函数式。Lambda表达式的引入是与这一趋势相适应的,它使得C++能够更好地与其他现代编程语言接轨。

综上所述,Lambda表达式的引入是为了提高C++的编程灵活性、代码的可读性和编写效率,同时也使得C++能够更好地适应现代编程的需求和趋势。

2 Lambda表达式使用详解

Lambda表达式是C++11中一个非常强大的特性,它允许你定义一个匿名函数对象,可以在定义它的地方立即使用,或者将其赋给一个变量以便稍后使用。Lambda表达式在STL算法、多线程编程、回调机制等多种场景中都非常有用。以下是一些详细的例子,展示了Lambda表达式在不同情况下的用法:

2.1 简单的Lambda表达式

参考代码如下:

// 定义一个Lambda表达式,接受两个int参数,返回它们的和
auto add = [](int a, int b) { return a + b; };
int result = add(2, 3); // 调用Lambda表达式,result 为 5

2.2 使用Lambda表达式与STL算法

参考代码如下:

#include <vector>
#include <algorithm>std::vector<int> numbers = {1, 2, 3, 4, 5};
// 使用Lambda表达式作为std::for_each的第一个参数
std::for_each(numbers.begin(), numbers.end(), [](int num) {std::cout << num << std::endl; // 打印每个数字
});
// 使用Lambda表达式进行排序,根据数字的奇偶性
std::sort(numbers.begin(), numbers.end(), [](int a, int b) {return a % 2 == 0 && b % 2 != 0;
});

2.3 捕获上下文变量

参考代码如下:

// 定义一些局部变量
int x = 10;
int y = 20;
// 定义一个Lambda表达式,捕获x和y
auto lambda = [&x, &y]() { return x + y; };
int result = lambda(); // 调用Lambda表达式,result 为 30

2.4 在多线程编程中使用Lambda表达式

参考代码如下:

#include <iostream>
#include <thread>void print(int n) {std::cout << "Hello from thread " << n << std::endl;
}int main() {std::thread t(print, 1); // 使用Lambda表达式启动线程t.join(); // 等待线程结束return 0;
}

2.5 Lambda表达式作为函数参数

参考代码如下:

// 定义一个接受Lambda表达式作为参数的函数。
void executeLambda(std::function<void()> lambda) {lambda(); // 调用传入的Lambda表达式
}int main() {executeLambda([]() {std::cout << "Lambda is called" << std::endl;});return 0;
}

2.6 使用Lambda表达式进行类型推导

参考代码如下:

// 使用auto推导Lambda表达式的类型。
auto square = [](int x) -> int {return x * x;
};
int squared = square(5); // squared 为 25

2.7 Lambda表达式与模板函数结合

参考代码如下:

template <typename Func>
void runFunc(Func f) {f();
}int main() {runFunc([]() {std::cout << "Hello from a template function!" << std::endl;});return 0;
}

2.8 Lambda表达式捕获所有局部变量

参考代码如下:

// 定义一些局部变量
int a = 5;
int b = 10;
// 定义一个Lambda表达式,捕获所有局部变量
auto lambda = [a, b]() {std::cout << "a = " << a << ", b = " << b << std::endl;
};
lambda(); // 输出:a = 5, b = 10

通过这些例子,我们可以看到Lambda表达式在C++11中的多样性和实用性。它不仅可以简化代码,还可以提高代码的可读性和可维护性。Lambda表达式的引入为C++编程带来了更多的灵活性和便利。


http://www.ppmy.cn/news/1405289.html

相关文章

IDEA跑Java后端项目提示内存溢出

要设置几个地方&#xff0c;都试一下吧&#xff1a; 1、默认是700&#xff0c;我们设置大一点&#xff08;上次配置了这儿就解决了&#xff09; 2、 3、 4、-Xmx4g

软件供应链安全:智慧城市建设的安全基石

2024年的两会上&#xff0c;数字经济再次成为热议话题。2024年政府工作任务中明确提出了“深入推进数字经济创新发展”。而其中的一项重点任务&#xff0c;便是建设智慧城市。 在智慧城市的建设中&#xff0c;软件供应链安全无疑是至关重要的一环。面对日益复杂的软件开发环境…

网站安全利剑:HTML代码加固实战手册

引言 HTML是网站开发的基础语言&#xff0c;它的安全性直接关系到网站的安全性。为了保障网站的安全性&#xff0c;我们需要加固HTML代码。本文将介绍一些具体方法&#xff0c;帮助你加固HTML代码&#xff0c;提高网站的安全性。 摘要 本文将介绍以下几种方法来加固HTML代码…

HarmonyOS 应用开发之通过数据管理服务实现数据共享静默访问

场景介绍 典型跨应用访问数据的用户场景下&#xff0c;数据提供方会存在多次被拉起的情况。 为了降低数据提供方拉起次数&#xff0c;提高访问速度&#xff0c;OpenHarmony提供了一种不拉起数据提供方直接访问数据库的方式&#xff0c;即静默数据访问。 静默数据访问通过数据…

CQI-17:2021 V2 英文 、中文版。特殊过程:电子组装制造-锡焊系统评审标准

锡焊作为一个特殊的工艺过程&#xff0c;由于其材料特性的差异性、工艺参数的复杂性和过程控制的不确定性&#xff0c;长期以来一直视为汽车零部件制造业的薄弱环节&#xff0c;并将很大程度上直接导致整车产品质量的下降和召回风险的上升。 美国汽车工业行动集团AIAG的特别工…

mysql闲谈

如何定位慢查询 1、测试环境压测时&#xff0c;有的接口非常慢&#xff0c;响应时间超过2秒以上。当时系统部署了运维的监控系统Skywalking&#xff0c;在展示报表中可以看到是哪儿个接口慢&#xff0c;可以看到SQL具体执行时间。 2、如果没有类似的监控系统&#xff0c;在Mysq…

IT库存管理

计算机资产由软件和硬件组件组成&#xff0c;需要在其整个生命周期内进行监控&#xff0c;IT 库存管理是识别、管理和维护组织的硬件和软件资产的过程&#xff0c;IT 资产的手动编译和核对非常费力且容易出错。 借助 IT 库存管理解决方案&#xff0c;可以跟踪、监控和管理计算…

【微服务】软件架构的演变之路

目录 单体式架构的时代单体式架构(Monolithic)优点缺点适用场景单体式架构面临诸多问题1.宽带提速&#xff0c;网民增多2.Web2.0时代的特点问题描述优化方向 集群优点缺点适用场景搭建集群后面临诸多问题用户请求问题用户的登录信息数据查询 改进后的架构 垂直架构优点缺点 分布…

Linux下I2C设备驱动:I2C设备和驱动匹配过程

一. 简介 Linux 内核也将 I2C 驱动分为两部分&#xff1a; (1) I2C 总线驱动&#xff0c; I2C 总线驱动就是 SOC 的 I2C 控制器驱动&#xff0c;也叫做 I2C 适配器驱动。 (2) I2C 设备驱动&#xff0c; I2C 设备驱动就是针对具体的 I2C 设备而编写的驱动。 本文来学习一下…

新网站秒收录技术,新网站百度收录时间

在建立新网站后&#xff0c;让它尽快被搜索引擎收录是网站主最为关注的事情之一。百度作为中国最大的搜索引擎&#xff0c;网站被其快速收录对于增加曝光和流量至关重要。本文将介绍一些新网站秒收录技术&#xff0c;以及一般情况下新网站被百度收录需要的时间。 新网站秒收录技…

游戏引擎架构01__引擎架构图

根据游戏引擎架构预设的引擎架构来构建运行时引擎架构 ​

YOLOV5 改进:更换主干网络为Resnet

1、前言 之前实现了yolov5更换主干网络为MobileNet和vgg网络 本章将继续将yolov5代码进行更改,通过引用官方实现的resnet网络,替换原有的yolov5主干网络 替换的效果如下: 2、resnet 网络结构 测试的代码为官方的resnet34 通过summary 打印的resnet网络结构如下 =======…

git diff

1. 如何将库文件的变化生成到patch中 git diff --binary commit1 commit2 > test.patch 打patch&#xff1a; git apply test.patch 2. 如何消除trailing whitespace 问题 git diff --ignore-space-at-eol commit1 commit2 > test.patch 打patch&#xff1a; git ap…

FastAPI+React全栈开发15 让我们构建一个展示API

Chapter03 Getting Started with FastAPI 15 Let’s Build a showcase API FastAPIReact全栈开发15 让我们构建一个展示API REST APIs are all about cycles of HTTP requests and responses, it is the engine that powers the web and is implemented in every web framew…

TCP Socket通信CAPL代码演示

TCP通信过程分为三个部分: 建立连接:三次握手数据传输关闭连接:四次挥手这些都可以通过socket套接字接口来实现。 Client: variables {const dword INVALID_SOCKET = 0xFFFFFFFF;dword clientSocket = INVALID_SOCKET;char …

CentOS离线安装命令

一.引言 某些CentOS安装后默认是没有部分Linux命令的&#xff0c;比如netstat和lsof&#xff1a; 一般情况下我们可以通过yum install安装这些命令。但是在CentOS无法访问公网的时候&#xff08;比如CentOS服务器部署在学校、军工等无法访问外网的环境&#xff09;&#xff0c…

广东开放大学2024春《互联网金融(本)》形成性考核一二三四总400题参考答案

答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 答案&#xff1a;更多答案&#xff0c;请关注【电大搜题】微信公众号 互联网金融的本质是 A. 双边市场经济 B. 平台经济 C. 多边…

理解游戏服务器架构-部署架构

目录 前言 我所理解的服务器架构 什么是否部署架构 部署架构的职责 进程业务职责 网络链接及通讯方式 与客户端的连接方式 服务器之间连接关系 数据落地以及一致性 数据库的选择 数据访问三级缓存 数据分片 读写分离 分布式数据处理 负载均衡 热更新 配置更新 …

hadoop 高可用(HA)、HDFS HA、Yarn HA

目录 hadoop 高可用(HA) HDFS高可用 HDFS高可用架构 QJM 主备切换&#xff1a; Yarn高可用 hadoop 高可用(HA) HDFS高可用 HDFS高可用架构 QJM 主备切换&#xff1a; Yarn高可用

1,static 关键字.Java

目录 1.概述 2.定义格式和使用 2.1 静态变量及其访问 2.2 实例变量及其访问 2.3 静态方法及其访问 2.4 实例方法及其访问 3.小结 1.概述 static表示静态&#xff0c;是Java中的一个修饰符&#xff0c;可以修饰成员方法&#xff0c;成员变量。被static修饰后的&#xff…