服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

释放 C++ 中 Lambda 表达式的强大威力

日期: 来源:Linux公社收集编辑:聆听世界的鱼

点击上方蓝字 ● 关注Linux公社     

Lambda 是 C++ 中的匿名函数(即没有函数名的函数),可以在定义和使用时内联。它们提供了一种方便的方式,将小的代码块作为参数传递给其他函数,或者在不需要创建命名函数的情况下定义一个函数。
Lambda 在 C++ 中提供了一种灵活而简洁的方式来编写类似函数的对象,并在现代 C++ 编程中被广泛使用。
Lambda 的定义使用以下语法:
[ capture list ] ( argument list ) -> return type { function body }
  • 捕获列表(capture list)用于指定 lambda 中可访问的来自外部作用域的变量。变量可以通过值捕获、引用捕获或使用 this 捕获。
  • 参数列表(argument list)指定将递给 lambda 的参数。
  • 返回类型(return type)指定 lambda 将返回的值的类型。如果未指定,则编译器将尝试推断其类型。
  • 函数体(function body)指定 lambda 被调用时将执行的代码。
以下是在C++中使用 lambda 的几种不同方式:
  1. 函数回调(Function Callbacks)
  2. 默认捕获(Capturing default)
  3. 值捕获(Capturing by value)
  4. 引用捕获(Capturing by reference)
  5. 可变 lambda(Mutable Lambdas)

1、函数回调
函数回调是将一个函数作为参数传递给另一个函数,并在接收函数稍后的时间调用该函数。您可以将 lambda 作为函数参数传递,其中它将在发生某个事件时执行。
示例:
#include <iostream>#include <algorithm>#include <vector>
int main() { std::vector<int> numbers = {1, 2, 3, 4, 5};
// Lambda 表达式,用于查找两个数字的和 auto sum = [](int a, int b) { return a + b; };
int result = std::accumulate(numbers.begin(), numbers.end(), 0, sum); std::cout << "Sum of elements in the vector: " << result << std::endl;
return 0;}
在这个例子中,sum 变量是一个Lambda表达式,它接受两个参数 a 和 b,并返回它们的总和。std::accumulate 函数接受数字向量、结果的初始值和 sum 函数(Lambda 表达式)。该函数计算向量中所有元素的总和并返回结果,该结果被打印在屏幕上。
另一个例子:
#include <iostream>#include <algorithm>#include <vector>
int main(){ std::vector<int> vec = { 1, 2, 3, 4, 5 }; int sum = 0; std::for_each(vec.begin(), vec.end(), [&sum](int x) { sum += x; }); std::cout << "The sum is: " << sum << std::endl; return 0;}
在这种情况下,lambda 表达式 [&sum](int x) { sum += x; } 被传递作为要应用于每个元素的函数。lambda 通过引用 & 捕获变量 sum,以便可以在 lambda 主体中进行修改。
两个例子都达到了相同的结果,但第二个例子使用了 std::for_each 算法和 lambda 表达式,这是在 C++ 中更现代、更简洁的技术。
2、默认捕获
当一个 lambda 表达式被声明时没有任何显式的捕获,其默认行为是通过引用捕获周围作用域中的变量。这被称为默认捕获。
例子:
#include <iostream>
int main() { int x = 42; auto f = [ ]() { std::cout << x << std::endl; }; f(); return 0;}
#include <iostream>
int main(){ auto square = [](int x) { return x * x; }; std::cout << "The square of 5 is: " << square(5) << std::endl; return 0;}
在第二个例子中,定义了一个 lambda 表达式并将其存储在名为 square 的变量中。这个 lambda 表达式接受一个 int 类型的参数 x,并返回 x * x 的值,即参数的平方。
在主函数中,这个 lambda 表达式被用作函数对象。通过传递一个值为 5 的参数来调用它,并使用 cout 流显示结果。
3、按值捕获
这是 lambda 表达式的最简单形式,其中你通过值传递变量给函数。当一个变量被按值捕获时,它的当前值被存储在闭包中,而当周围作用域中的变量发生改变时,它的值不会被更新。这可以通过将变量包含在方括号 [ ] 中来实现。
例子:
#include <iostream>
int main() { int x = 42; auto f = [x]() { std::cout << x << std::endl; }; f(); return 0;}
#include <iostream>
int main() { int x = 42; auto f = [x](int y) { std::cout << x+y << std::endl;}; f(1); return 0;}
4、按引用捕获
你可以通过使用 & 符号将变量传递给 lambda 表达式来按引用捕获变量。当一个变量被按引用捕获时,它的当前值被存储在闭包中,并且在周围作用域中变量发生变化时被更新。这是通过在方括号[ ]中在变量前加上取地址运算符 & 来实现的。
例子:
#include <iostream>
int main() { int x = 42; auto f = [&x]() { std::cout << x << std::endl; }; f(); return 0;}
#include <iostream>
int main() { int x = 10;
auto add_one = [&x]() { ++x; }; add_one(); std::cout << x << "\n";
return 0;}
#include <iostream>
int main() { int x = 42; auto f = [&x]() { std::cout << x << std::endl; }; f(); return 0;}
5、可变Lambda表达式
默认情况下,由 lambda 表达式捕获的变量是常量,不能在 lambda 表达式体内修改。如果你想要在 lambda 表达式中修改捕获的变量,你可以将 lambda 表达式设为可变。可变lambda允许捕获的变量被修改。这是通过在方括号 [ ] 中包含可变关键字来实现的。
例子:
#include <iostream>
int main() { int x = 42; auto f = [x]() mutable { std::cout << ++x << std::endl; }; f(); return 0;}
lambda 表达式类似于普通函数,但它们有一些关键的区别。例如,lambda 表达式的类型没有被显式指定,但可以由编译器推断出来。此外,lambda 表达式可以从周围的作用域中捕获变量,这使得它们非常适用于创建闭包和在 C++ 中使用函数式编程概念。
与传统函数相比,lambda 表达式具有一些性能优势:
  • 内联函数:编译器会自动将 lambda 表达式内联,这意味着它们的代码直接插入到调用函数中。这可以减少函数调用的开销并提高性能。
  • 避免命名函数的开销:lambda 表达式没有名称,因此它们不必被声明和存储在符号表中,这可以减少开销并提高性能。
  • 改善高速缓存局部性:lambda 表达式可以在同一个函数中定义和使用,这意味着lambda使用的代码和数据将存储在与调用代码相同的高速缓存行中。这可以改善高速缓存局部性并降低高速缓存失效的成本。
  • 减小代码大小:lambda 表达式通常比命名函数小,并且它们不需要外部函数调用,这可以减小编译代码的大小并提高性能。
  • 增加灵活性:lambda 表达式可以用来将函数作为参数传递给其他函数,这提供了更大的灵活性,可以改善性能,减少重复代码的需求。

  • 提高可读性:lambda 表达式可以通过以紧凑而自包含的方式封装复杂的逻辑来使代码更易于阅读。这可以通过使代码更易于理解和维护来提高性能。




总之,与传统函数相比,lambdas 可以通过减少开销、提高缓存位置、减少代码大小、提高灵活性和提高可读性来提高性能。

感谢 Linux迷 www.linuxmi.com 的精彩分享。
OK,这就是本文的内容。如果还有什么疑问,请在下面的评论区告诉我们。
需要 Linux 精美艺术壁纸的朋友请加小编微信linuxgs口令壁纸)。
来自:Linux迷
链接:https://www.linuxmi.com/c-lambda.html
关注我们

长按或扫描下面二维码关注 Linux公社



关注 Linux公社,添加“ 星标 

每天 获取 技术干货,让我们一起成长

合作联系:root@linuxidc.net

相关阅读

  • 睡眠混淆绕过Windows CFG检测保护机制

  • 01CFG&kCFG‍‍‍‍‍‍‍‍控制流防护(CFG)及其在内核中的实现称为kCFG,是Microsoft的控制流完整性(CFI)版本。CFG的工作原理是检查在使用CFG编译的模块的应用程序内部的间接
  • Spring Boot 整合 Groovy 脚本,实现动态编程

  • 关注我,回复关键字“spring”,免费领取Spring学习资料。来源:blog.csdn.net/weixin_33005117/article/details/126712394Groovy简介Groovy 是增强 Java 平台的唯一的脚本语言。
  • Bash 特殊变量,功能强大的 Shell

  • 点击上方蓝字 ● 关注Linux公社 Bash 是一个功能强大的 Shell,提供了各种特殊变量,可以用于操作和控制脚本的行为。这些变量提供了有关脚本运行环境的基本信息,包括命令行
  • 这才叫绩效考核管理,你那只是扣工资!

  • 我想,提到“绩效考核”这四个字,估计要有很多HR头要疼了,绩效考核到底要怎么才能做好呢?绩效考核是支撑一个企业的重要支柱,考核的主要目的就是:通过考核进行薪酬的合理分配,以调动
  • Pandas 必知必会的使用技巧

  • 来源:网络本期的主题是关于python的一个数据分析工具pandas的,归纳整理了一些工作中常用到的pandas使用技巧,方便更高效地实现数据分析。文章很短,不用收藏就能Get~1.计算变量缺
  • 【第2890期】never 和 unknown 的优雅之道

  • 前言3月份又到尾巴了。今日前端早读课文章由 @longgeng 分享,公号:腾讯 IMWeb 前端团队授权。正文从这开始~~TypeScript 在版本 2.0 和 3.0 分别引入了 “never” 和 “unknown
  • 拦截Windows关机消息

  • 本文为看雪论坛优秀文章看雪论坛作者ID:0346954写了一个小工具,可以通过Hook Winlogon进程主模块的导入表、延迟导入表来拦截对于User32!ExitWindowsEx函数的调用。整个步骤如

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • 释放 C++ 中 Lambda 表达式的强大威力

  • 点击上方蓝字 ● 关注Linux公社 Lambda 是 C++ 中的匿名函数(即没有函数名的函数),可以在定义和使用时内联。它们提供了一种方便的方式,将小的代码块作为参数传递给其他函数
  • GDC微软游戏案例发布:网易《永劫无间》

  • 网易早在2001年就正式成立了在线游戏事业部,致力于网络游戏产品的研发和运营,经过20多年的快速发展,网易已跻身全球七大游戏公司之列。目前,网易正在运营中的游戏产品有100余款,
  • 两年没写青团,今年又憋不住了……

  • 青团,春天网红食物里的最大IP。我们从2017年就开始在测评青团,眼睁睁看着它从绿到红到紫,从一个时令糕团,变成了一个青团的多元宇宙;)今年的青团斗争,更是格外激烈。不单是生鲜电商
  • ChatGPT第一个淘汰的是我爸

  • 前两天在排队吃饭时,突然来了个电话,我一看是我妈,心窝子一抽抽。在外漂泊久了有个感受,家里突然来电话,八成不是什么好事,要么有人生病了,去世了,或者被诈骗了等等,总之我小心翼翼地
  • 一个规则汇总8个站,绝对够用!

  • 不星标可能收不到消息,记得星标公众号回复QQ群获取群号前言最近看到有人汇总了8个非常不错的网站,因此专门写了个小程序规则分享给大家,取名MusicMusic小程序包含俄罗斯网站MP3