C++ Lambda表达式笔记

news/2024/11/19 20:25:03/文章来源:https://www.cnblogs.com/lyx9785/p/18555520

1. 什么是 Lambda 表达式?

Lambda 表达式是 C++11 引入的一种特性,允许定义匿名函数(没有名字的函数),并且可以像普通函数一样调用,甚至可以作为参数传递给其他函数。

基本语法:

[capture_list](parameters) -> return_type { function_body };
  • [capture_list]:捕获列表,决定外部变量如何被 lambda 捕获。
  • (parameters):参数列表,与普通函数的参数类似。
  • -> return_type(可选):返回类型,通常可以省略,由编译器自动推断。
  • { function_body }:函数体,包含要执行的具体逻辑。

2. Lambda 表达式的基本用法

  • 无参数、无返回值

    []() { std::cout << "Hello, Lambda!" << std::endl; }();
    

    输出:

    Hello, Lambda!
    
  • 有参数、返回值

    auto add = [](int a, int b) { return a + b; };
    std::cout << add(2, 3) << std::endl;  // 输出 5
    
  • 显式指定返回类型

    auto divide = [](int a, int b) -> double {return static_cast<double>(a) / b;
    };
    std::cout << divide(5, 2) << std::endl;  // 输出 2.5
    

3. 捕获列表([capture_list]

捕获列表决定 lambda 如何访问外部作用域中的变量。可以按值捕获或按引用捕获。

(1) 空捕获列表:[]
  • 不捕获任何外部变量。
  • 仅适用于 lambda 完全独立的情况。

示例:

auto print = []() { std::cout << "Independent Lambda" << std::endl; };
print();
(2) 按值捕获:[x]
  • 捕获外部变量 x 的副本,lambda 内的修改不会影响原变量。

示例:

int x = 5;
auto lambda = [x]() { std::cout << x << std::endl; };
lambda();  // 输出 5
x = 10;    // 修改原变量
lambda();  // 仍输出 5
(3) 按引用捕获:[&x]
  • 捕获外部变量 x 的引用,lambda 内的修改会影响原变量。

示例:

int x = 5;
auto lambda = [&x]() { x += 10; };
lambda();
std::cout << x << std::endl;  // 输出 15
(4) 捕获所有外部变量:[=][&]
  • [=]:按值捕获所有外部变量。
  • [&]:按引用捕获所有外部变量。

示例:

int x = 5, y = 10;
auto lambda1 = [=]() { std::cout << x + y << std::endl; };  // 按值捕获
auto lambda2 = [&]() { x += y; };                          // 按引用捕获
lambda1();  // 输出 15
lambda2();
std::cout << x << std::endl;  // 输出 15
(5) 混合捕获:[=, &x][&, x]
  • [=, &x]:按值捕获所有变量,但对 x 按引用捕获。
  • [&, x]:按引用捕获所有变量,但对 x 按值捕获。

示例:

int x = 5, y = 10;
auto lambda = [=, &y]() { y += x; };  // x 按值,y 按引用
lambda();
std::cout << y << std::endl;  // 输出 15

4. 使用 Lambda 表达式排序

Lambda 表达式经常用于自定义排序规则,例如在 std::sort 中。

  • 升序排序

    std::vector<int> vec = {5, 2, 9, 1};
    std::sort(vec.begin(), vec.end(), [](int a, int b) { return a < b; });
    // vec: {1, 2, 5, 9}
    
  • 降序排序

    std::sort(vec.begin(), vec.end(), [](int a, int b) { return a > b; });
    // vec: {9, 5, 2, 1}
    
  • 复杂排序规则

    std::sort(vec.begin(), vec.end(), [](int a, int b) {if (a % 2 == b % 2) return a > b;  // 同为奇数或偶数,按降序return a % 2 < b % 2;              // 偶数优先
    });
    // 假设 vec = {5, 2, 4, 7, 8}
    // 排序后:{8, 4, 2, 7, 5}
    

5. Lambda 表达式的实际应用场景

  1. 代替普通函数:用于实现一次性的功能,减少定义单独函数的冗余。
  2. 自定义排序:灵活定义排序规则(如 std::sort)。
  3. 回调函数:用于事件响应或异步处理(如 std::for_each)。
  4. 函数式编程:与标准库的函数式接口(如 std::transform)结合使用。
  5. 捕获变量用于计算:简化闭包的实现。

6. 示例:捕获外部变量的高级应用

int base = 10;
auto multiplier = [base](int x) { return base * x; };std::cout << multiplier(2) << std::endl;  // 输出 20
  • 捕获 base,并使用其值进行计算。
  • 这使得 lambda 可以与外部变量结合实现更多功能。

7. 总结

Lambda 表达式的优势:

  1. 简洁:减少了定义额外函数的冗余代码。
  2. 灵活:可以捕获外部变量,轻松实现闭包。
  3. 高效:与标准库算法结合(如 std::sortstd::transform),使代码更清晰。

常用模式:

  • 无捕获[]() {}
  • 按值捕获[x]() {}[=]() {}
  • 按引用捕获[&x]() {}[&]() {}
  • 混合捕获[=, &x][&, x]

Lambda 表达式是现代 C++ 编程的重要工具,值得熟练掌握!

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

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

相关文章

从汇编看函数调用传参过程

1 示例代码 #include <stdio.h>int func(int param1 ,int param2,int param3) {int var1 = param1;int var2 = param2;int var3 = param3;printf("var1=%d,var2=%d,var3=%d",var1,var2,var3);return var1; }int main(int argc, char* argv[]) {int result = fu…

IDEA如何导入外部依赖的jar包

前言 大家好,我是小徐啊。今天小徐要给大家介绍下,在使用IDEA开发java应用时,如何导入第三方的jar包,注意不是通过maven的方式导入。这种情况就是这个jar包比较特殊,可能并不存在于仓库中,需要手动引入。 如何导入jar包 首先,我们需要在资源目录下新建一个文件夹,我一般…

Cut the Sequence

Cut the Sequence P10977 Cut the Sequence 前言 单调队列优化 dp 的好题,思维难度大细节多。因为觉得自己看不懂其他题解,在看完 y 总的讲解后豁然开朗,所以写这篇题解来巩固一下。包括完整的细节分析和思考过程,或许很多大佬都不需要 qwq。叠甲完毕,下面开始正文。 分析…

20222408 2024-2025-1 《网络与系统攻防技术》实验五实验报告

1.实验内容 1.1实验要求 (1)选择一个DNS域名进行查询,获取如下信息:DNS注册人及联系方式、该域名对应IP地址、IP地址注册人及联系方式、IP地址所在国家、城市和具体地理位置。 (2)尝试获取QQ中某一好友的IP地址,并查询获取该好友所在的具体地理位置。 (3)使用nmap开源…

[考试记录] 2024.11.19 noip模拟赛17

T1 选取字符串warning❗:本题解 前缀 含量过高。挺典的 kmp。考虑到题目中的串都是一个串的前缀,那么所选出来的串,他们的前缀一定是最短的那个串。不妨直接枚举每一个前缀,也就是枚举每一个串,看他们是否可以作为前缀出现,hash即可,复杂度 \(\mathcal{O}(N^2)\)。换个…

【淘汰9成NLP工程师的常识题】多头注意力相对于多头注意力有什么优势?

【淘汰9成NLP工程师的常识题】多头注意力相对于多头注意力有什么优势? 重要性:★★★ 💯 这是我【淘汰9成NLP工程师的常识题】多头注意力相对于多头注意力有什么优势? 重要性:★★★ 💯这是我常用的一个面试题。看似简单的基础常识题,但在面试中能准确回答的不足10% …

多校A层冲刺NOIP2024模拟赛24

多校A层冲刺NOIP2024模拟赛24\(T1\) A. 选取字符串 \(100pts\)考虑建出失配树,然后等价于询问 \(\sum\limits_{S \sube \{ 0,1,2, \dots ,n \},|S|=k}dep_{\operatorname{LCA}\{ S \}}^{2}\) 。不妨从 \(\operatorname{LCA}\) 的角度考虑,统计 \(x\) 能作为多少个 \(|S|\) 的…

在微信中使用AI聊天机器人

微信是中国最流行的社交通讯软件,具有庞大的用户基础。ChatGPT是由 OpenAI 开发的、当前最先进的AI聊天机器人,ChatGPT 尤其是在理解和生成自然对话方面表现出色,能够进行流畅且连贯的交流。对中国人而言,将 ChatGPT 集成到微信中,可以在一个熟悉的环境中体验到最新的人工…

protodep踩坑

在使用微服务框架go-zero时,服务拆分比较多,每更新一个服务的proto文件,都要手动复制pb文件到调用的服务里面,新系统开发的时候决定用protodep解决这个问题。 protodep 是一款专为Protocol Buffers接口描述语言文件设计的依赖管理工具。它解决了在使用gRPC时,如何有效控制…

虚幻4 蓝图无法保存 解决方法

蓝图类只能存放在 Blueprints文件夹内,创建在其他文件夹的蓝图类无法保存。 可以看到无法将蓝图拖动到其他文件夹内。这是一个存放在其他文件夹下的蓝图类:当尝试按Ctrl+shift+A保存时,将出现如下错误:解决方法是,将当前蓝图删除(注意,如果该蓝图从某个C++类继承而来,那…

理解进程调度时机跟踪分析进程调度与进程切换的过程

张晓攀+原创作品转载请注明出处+《Linux内核分析》MOOC课程https://mooc.study.163.com/course/1000029000 实验八——理解进程调度时机跟踪分析进程调度与进程切换的过程 一、理解Linux系统中进程调度的时机 在 Linux 内核中,schedule() 函数是核心的进程调度机制。它的主要作…

李继刚Lisp提示词灵感之源:压缩推动进步

探秘李继刚Lisp提示词压缩表达的灵感来源:德国计算机科学家尤尔根施密德胡伯提出,智能系统通过学习新技能来更高效地预测或压缩信息,这种内在动力推动了好奇心和创造力的发展,适用于从婴儿探索世界到科学家发现新规律的各种场景。前面在文章《 访谈李继刚:从哲学层面与大模…