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

说明: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.rhkb.cn/news/293905.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中常见的锁策略

目录 乐观锁 vs 悲观锁 悲观锁: 乐观锁&#xff1a; 重量级锁 vs 轻量级锁 ⾃旋锁&#xff08;Spin Lock&#xff09; 公平锁 vs 非公平锁 可重⼊锁 vs 不可重入锁 读写锁 乐观锁 vs 悲观锁 悲观锁: 总是假设最坏的情况&#xff0c;每次去拿数据的时候都认为别…

【DETR系列目标检测算法代码精讲】01 DETR算法03 Dataloader代码精讲

与一般的Dataloader的区别在于我们对图像进行了随机裁剪&#xff0c;需要进行额外的操作才能将其打包到dataloader里面 这一段的代码如下&#xff1a; if args.distributed:sampler_train DistributedSampler(dataset_train)sampler_val DistributedSampler(dataset_val, shu…

C语言动态内存讲解+通讯录2.0

文章目录 前文malloc和freecallocrealloc枚举常量的简单说明及使用 通讯录2.0动态开辟通讯录,满了就扩容保存数据和载入数据 通讯录2.0演示推荐好用的软件 前文 本文主要介绍动态开辟的几个函数,以及改进之前的通讯录。 我们局部变量等是在栈区上开辟空间的,而我们动态开辟的空…

非wpf应用程序项目【类库、用户控件库】中使用HandyControl

文章速览 前言参考文章实现方法1、添加HandyControl包&#xff1b;2、添加资源字典3、修改资源字典内容 坚持记录实属不易&#xff0c;希望友善多金的码友能够随手点一个赞。 共同创建氛围更加良好的开发者社区&#xff01; 谢谢~ 前言 wpf应用程序中&#xff0c;在入口项目中…

Linux 给网卡配置ip

ip addr | grep eth9 ifconfig eth9 10.0.0.2 netmask 255.255.255.0 up

linux安装git

一、下载git 注意&#xff1a;不要下载最新版本的git&#xff0c;否则可能安装会失败&#xff0c;缺失很多依赖文件&#xff0c;解决起来费时费力&#xff0c;还可能不成功 尽量下载前几年的&#xff0c;甚至10年前的都可以 下载地址&#xff1a;https://mirrors.edge.kerne…

Codigger用户篇:安全、稳定、高效的运行环境(一)

在当今数字化时代&#xff0c;个人数据的安全与隐私保护显得尤为重要。为了满足用户对数据信息的安全需求&#xff0c;我们推出Codigger分布式操作系统&#xff0c;它提供了一个运行私有应用程序的平台&#xff0c;旨在为用户提供一个安全、稳定、高效的私人应用运行环境。Codi…

3.26号arm

1. SPI相关理论 1.1 概述 spi是一种同步全双工串行总线&#xff0c;全称串行外围设备接口 通常SPI通过4个引脚与外部器件相连&#xff1a; MISO&#xff1a;主设备输入/从设备输出引脚。该引脚在从模式下发送数据&#xff0c;在主模式下接收数据。 MOSI&#xff1a;主设备输…

Go-Gin-Example 第八部分 优化配置接口+图片上传功能

文章目录 前情提要本节目标 优化配置结构讲解落实修改配置文件优化配置读取及设置初始化顺序第一步 验证 抽离file 实现上传图片接口图片名加密封装image的处理逻辑编写上传图片的业务逻辑增加图片上传的路由 验证实现前端访问 http.FileServerr.StaticFS修改文章接口新增、更新…

以太网/USB 数据采集卡 24位16通道 labview 256K同步采样

XM7016以太网SUB数据采集卡 XM7016是一款以太网/USB高速数据采集卡&#xff0c;具有16通道真差分输入&#xff0c;24位分辨率&#xff0c;单通道最高采样率256ksps. 16通道同步共计4.096Msps、精密前置增益放大、集成IEPE/ICP硬件支持的特点。本产品采用了多个高精度24位ADC单元…

学习JavaEE的日子 Day32 线程池

Day32 线程池 1.引入 一个线程完成一项任务所需时间为&#xff1a; 创建线程时间 - Time1线程中执行任务的时间 - Time2销毁线程时间 - Time3 2.为什么需要线程池(重要) 线程池技术正是关注如何缩短或调整Time1和Time3的时间&#xff0c;从而提高程序的性能。项目中可以把Time…

【 MyBatis 】| 关于多表联查返回 List 集合只查到一条的 BUG

目录 一. &#x1f981; 写在前面二. &#x1f981; 探索过程2.1 开端 —— 开始写 bug2.2 发展 —— bug 完成2.3 高潮 —— bug探究2.4 结局 —— 效果展示 三. &#x1f981; 写在最后 一. &#x1f981; 写在前面 今天又是 BUG 气满满的一天&#xff0c;一个 xxxMapper.xm…

跑spark的yarn模式时RM连不上的情况

在linux控制台跑spark on yarn一个测试案例&#xff0c;日志中总显示RM连yarn服务的时候是&#xff1a;0.0.0.0:8032 具体情况如下图&#xff1a; 我问题出现的原因&#xff0c;总结如下&#xff1a; 1.防火墙没关闭&#xff0c;关闭 2.spark-env.sh这个文件的YARN_CONF_DIR…

MyBatis基础使用

MyBatis首页https://mybatis.net.cn/ MyBatis细节注意&#xff0c;让你更加熟悉MyBatishttps://blog.csdn.net/m0_61160520/article/details/137173558?spm1001.2014.3001.5501 1.项目目录 2.数据库 CREATE DATABASE mybatis-example;USE mybatis-example;CREATE TABLE t_e…

Linux文件与进程交互的窥探者lsof

lsof 是一个 Linux 和 UNIX 系统中的实用工具,用于列出系统中打开文件的所有信息。这个名字代表 “List Open Files”,但它也可以显示进程相关的其他信息,如: 打开的文件描述符列表 打开网络连接的列表 被进程使用的信号和内核对象等 在Linux系统中,有一个经典的概念: …

vue3+threejs新手从零开发卡牌游戏(二十):添加卡牌被破坏进入墓地逻辑

在game目录下新建graveyard文件夹存放墓地相关代码&#xff1a; game/graveyard/p1.vue&#xff0c;这里主要设置了墓地group的位置&#xff1a; <template><div></div> </template><script setup lang"ts"> import { reactive, ref,…

【刷题】 二分查找入门

送给大家一句话: 总有一天&#xff0c;你会站在最亮的地方&#xff0c;活成自己曾经渴望的模样—— 苑子文 & 苑子豪《我们都一样 年轻又彷徨》 二分查找入门 1 前言2 Leetcode 704. 二分查找2.1 题目描述2.2 算法思路 3 Leetcode 34. 在排序数组中查找元素的第一个和最后…

求组合背包II(acwing)

题目描述&#xff1a; 给定n组循问&#xff0c;每组询问给定两个整数a&#xff0c;b&#xff0c;请你输出Ca^b mod (1e9 7)的值&#xff0c;。 输入格式&#xff1a; 第一行包含整数n。 接下来2行&#xff0c;每行包含一组a和b。 输出格式&#xff1a; …

Leetcode 4.1

LeetCode 热题 100 贪心算法1.买卖股票的最佳时机2.跳跃游戏3.跳跃游戏 II4.划分字母区间 区间合并1.合并区间 贪心算法 1.买卖股票的最佳时机 买卖股票的最佳时机 买的那天一定是卖的那天之前的最小值。 每到一天&#xff0c;维护那天之前的最小值即可。 在题目中&#xff0…

面试题:MySQL 优化篇

定位慢查询 &#x1f496; 开源工具 调试工具&#xff1a;Arthas&#xff08;阿尔萨斯&#xff09;运维工具&#xff1a;Prometheus&#xff08;普罗米修斯&#xff09;、Skywalking &#x1f496; MySQL 慢查询日志 # 开启 MySQL 慢查询日志开关 slow_query_log1 # 设置慢…