当前位置: 首页 > ops >正文

C++ Lambda 表达式介绍


author: hjjdebug
date: 2025年 05月 16日 星期五 09:11:13 CST
descripton: C++ Lambda 表达式介绍


文章目录

  • 0. 测试代码:
  • 1. Lambda表达式是什么?
  • 2. lambda 表达式本质上是一个匿名类,
  • 3. 为什么叫"函数对象" (Functor)?
  • 4 lambda 表达式有捕获变量的能力:

为了说明问题,先给一段简单的测试代码.

0. 测试代码:

#include <stdio.h>
constexpr auto square = [](int x) constexpr { return x * x; };
constexpr int val = square(4);  // 编译时计算得 16
int main()
{printf("%d\n",val);int v=square(3); //编译时计算得9printf("%d\n",v);int a=10;auto add_a = [a](int x){return x+a;};v=add_a(20);printf("%d\n",v);return 0;
}

运行代码:
$ ./tt
16
9
30

1. Lambda表达式是什么?

Lambda表达式(也称为lambda函数或匿名函数)是一种语法糖,
当我们书写代码时,发现需要定义一个函数, 但此时我们无需去另外找一个地方去书写这个函数.
而是就在你需要调用的地方开始书写函数体代码.
好处是方便, 随用随定义. 调用和实现是紧挨着的.
这个Lambda表达式的格式如下:
[capture] (parameters) -> return_type { body }

捕获列表(capture) :定义了Lambda表达式可以访问的外部变量。捕获方式有两种:按值捕获(value)和按引用捕获(reference)。
参数列表(parameters) :定义了Lambda表达式的输入参数。如果不需要参数,可以省略参数列表的括号。
返回类型(return_type) :定义了Lambda表达式的返回类型。如果不需要显式指定返回类型,可以使用auto或省略返回类型。
函数体(body) :包含Lambda表达式的执行代码。
如果与函数比较, 我们会发现它有参数列表,有返回值和函数体,但没有函数名.多了一个捕获列表.

2. lambda 表达式本质上是一个匿名类,

编译器会自动生成一个匿名类(未命名的类),
以第一个lambda 表达式为例.
其大致等价于:
class __AnonymousLambdaClass {
public:
int operator()(int x) const {
return x * x;
}
};
实例化这个类,得到一个对象,起名square, 属于函数对象

auto square = [](int x) { return x * x; }; 语句解释
[] (这里为空表示不捕获任何外部变量)
(int x) 是参数列表
{ return x * x; } 是函数体
square : 类对象

看看gdb中打印的,这个对象就是一个没有数据域的对象.
(gdb) p square
$1 = {}
看看gdb中打印的类型. 写的很简单.
(gdb) ptype square
type = const struct <lambda(int)> {
}

3. 为什么叫"函数对象" (Functor)?

因为该匿名类重载了 operator(),使得对象可以像函数一样调用:
int result = square(5); // 等价于 square.operator()(5);

其实square 函数对象等价于传统的square函数
int square(int x) { return x * x; }
函数对象的调用square(5) 也与传统的函数调用square(5)一致.

4 lambda 表达式有捕获变量的能力:

如果 lambda 捕获了变量(例如 [a]),生成的类会有对应的成员变量:
有人把捕获变量的能力叫闭包. 也有人叫携带状态

举例:
int a = 10;
auto add_a = [a](int x) { return x + a; };
// 捕获列表中有一个外部变量a,
// 生成类中会有一个成员变量存储 a 的副本, 这就是捕获的实现.
class __AdderLambdaClass {
private:
int _a; // 捕获的变量
public:
__AdderLambdaClass(int a) : _a(a) {}
int operator()(int x) const {
return x + _a;
}
};
看看gdb 中的输出, 对象以及类型一目了然!
(gdb) p add_a (对象)
$1 = {
__a = 10
}
(gdb) ptype add_a (类)
type = struct <lambda(int)> {
int __a;
}

所以说,lambda 表示式并不是什么神秘的东西, 它是一种替代传统的
定义函数,调用函数二步走,改变为定义lambda表达式和调用它一步走(代码都在一起)的简易处理手段.
其内部实现方式是定义了一个匿名类并重载了operator()函数,使得对象能像函数一样调用.

http://www.xdnf.cn/news/6496.html

相关文章:

  • 人工智能100问☞第24问:什么是生成对抗网络(GAN)?
  • 互联网应用的安全防线-身份证实名认证api-身份证三要素验证
  • BUUCTF——web刷题第一页题解
  • 【Java实战】IO流(转换流,打印流,数据流,序列化流)
  • Java随机生成邀请码 (包含字母大小写+数字)
  • 2022 Hubei Provincial Collegiate Programming Contest
  • 栈的计算方式和表达方式
  • 【深度剖析】安踏体育的数字化转型(上篇1)
  • 3D曲面上的TSP问题(二):ACO蚁群算法 + 2-opt搜索求解TSP问题
  • 讯联云库项目开发技术栈总结(一)
  • Linux系统发布.net core程序
  • 电脑自带画图工具,提取颜色
  • 软件工程之软件产品的环境
  • P1260 工程规划
  • 记录算法笔记(2025.5.15)二叉树的层序遍历
  • RK3588 桌面系统配置WiFi和蓝牙配置
  • SQL优化总结
  • vue使用vite, 渲染glb模型时报错
  • 【GESP真题解析】第 9 集 GESP 一级 2023 年 9 月编程题 2:小明的幸运数
  • 检测按键抖动的时间
  • ivx 开发者如何通过 BI 引擎实现应用功能精准优化
  • 深光-谷歌TV TADA/奈飞Netflix/亚马逊Prime Video/YouTube等测试外包服务
  • 【蓝桥杯嵌入式】【模块】四、按键相关配置及代码模板
  • 【数据结构】队列
  • 如何在WooCommerce中设置Stripe
  • 了解光学影像
  • Cinema4D 26.014
  • 软考软件评测师——计算机组成与体系结构(CPU指令系统)
  • SPL做量化---DMI(动向指标)
  • jq安装与使用