嵌入式AI学习打卡 07 现代C++ lambda表达式

66 阅读2分钟

适合谁看:资深的嵌入式系统底层专家。技能栈(C、SoC、Bootloader、驱动、系统移植、DSP优化、Cache调优、功耗分析)是芯片设计的核心和基础,具备从硬件(SoC)底层固件(ROM Bootloader)再到操作系统层(驱动、RTOS)的全栈知识和实战经验,希望向嵌入式场景的AI部署方向拓展,寻求新的发展空间。


C风格编程中,可以用函数指针把一个函数传给另一个函数。但是函数指针不好维护,并且往往难以理解,因为函数指针对应的函数可能定义在源码的其他位置,离调用的地方很远,而且函数指针也不是类型安全的(type-safe)。现代C++提供了函数对象(function objects),即可重载()运算符的类,这使得它们能像函数一样被调用。

创建函数对象最便捷的方法就是用lambda表达式,下面这个例子说明了如何使用lambda表达式传递函数对象,该对象会在find_if遍历vector中每个元素时被调用。

std::vector<int> v {1,2,3,4,5};
    int x = 2;
    int y = 4;
    auto result = find_if(begin(v), end(v), [=](int i) { return i > x && i < y; });

这里的lambda表达式[=](int i) { return i > x && i < y; }可以解释为有一个类型为int的,返回值为bool类型(这里使用了auto)的函数。注意外部作用域的变量x和y可以在lambda中使用。[=]表明这些变量是通过值捕获的;换句话说,lambda 表达式拥有这些值的自己的副本, 修改lambda内的副本不会影响外部原始变量

int x = 10, y = 20;
auto lambda = [=]() { 
    // lambda 内部有 x 和 y 的独立副本
    return x + y;  // 使用副本值:10 + 20
};
x = 100;  // 修改外部 x
lambda();  // 仍然返回 30(使用捕获时的副本值)

各种捕获方式:

  • [x]:按值捕获特定变量
  • [&y]:按引用捕获特定变量
  • [=]:按值捕获所有外部变量
  • [&]: 按引用捕获所有外部变量

捕获(Capture)机制是 lambda 表达式相较于传统函数指针的核心优势之一,它避免了显式传参的繁琐,尤其在涉及多个上下文变量时能显著提升代码的简洁性和可读性。