C++11 lambda表达式

概念

  • 本质 = 编译器自动生成的 匿名函数对象(仿函数)
  • 可以定义在函数内部(普通函数不行)
  • 没有可写出来的类型名 → 必须用 auto 接收

例子:

cpp 复制代码
auto func = [](){ cout << "hello"; };

lambda表达式格式

cpp 复制代码
[捕获列表] (参数) -> 返回值 { 函数体 }
  1. [] 捕获列表

    • 捕获外部变量给 lambda 用
    • 不能为空 ,哪怕不捕获也要写 []------必写
    • 捕获方式:
      • [=] 值捕获
      • [&] 引用捕获
      • [x, &y] 单独捕获
  2. (参数)

    • 和普通函数参数一样
    • 没有参数可以省略 ()
  3. -> 返回值

    • 返回值明确时 可以省略
    • 无返回值也可以省略
  4. { 函数体 }

    • 和普通函数逻辑一样
    • 不能为空 ,至少写 {}------必写

3. 最简单的 4 种写法(一看就会)

  1. 无参无返
cpp 复制代码
[]{};
  1. 有参
cpp 复制代码
[](int a, int b){ return a+b; };
  1. 有返回值(可省略->)
cpp 复制代码
[](int a)->int{ return a*2; };
  1. 捕获外部变量
cpp 复制代码
int x = 10;
auto f = [x](){ cout << x; };

捕捉列表

为什么需要捕捉?

Lambda 默认只能访问自身参数和函数体内变量 ,要使用外层作用域变量 ,必须在 [] 里声明捕捉。

三种捕捉方式

1. 显式捕捉(手动指定变量)

  • 语法:[变量名, &变量名, ...]
  • 含义:
    • [x, y]:x、y 为值捕捉(拷贝一份,lambda 内是副本)
    • [&z]:z 为引用捕捉(直接用原变量,修改会影响外部)
  • 例子:[x, y, &z] → x、y 值捕捉,z 引用捕捉

2. 隐式捕捉(自动识别变量)

  • 语法:
    • [=]隐式值捕捉 → 编译器自动捕捉 lambda 中用到的所有外层变量,全部按值传递
    • [&]隐式引用捕捉 → 编译器自动捕捉 lambda 中用到的所有外层变量,全部按引用传递

3. 混合捕捉(显式 + 隐式结合)

  • 语法规则:
    • 第一个元素必须是 =&
    • [=, &x]:其余变量隐式值捕捉,x 单独引用捕捉
      例子:[&, x, y]:其余变量隐式引用捕捉,x、y 单独值捕捉
  • 注意:
    • = 开头时,后面只能跟引用捕捉的变量
    • & 开头时,后面只能跟值捕捉的变量

捕捉范围与特殊变量

  • 局部域 lambda :只能捕捉 lambda 定义之前的局部变量
  • 静态局部变量 / 全局变量不需要捕捉,可以直接在 lambda 里使用
  • 全局 lambda :定义在全局作用域时,捕捉列表必须为空(没有可捕捉的局部变量)

关于const 与 mutable 修饰

  • 默认:值捕捉的变量在 lambda 内是 const 的,不能修改
  • mutable 修饰:
    • 放在参数列表后:[x]() mutable { x++; }
    • 作用:取消值捕捉变量的 const 性,允许在 lambda 内修改
    • 注意:修改的是副本 ,不会影响外部原变量;且参数列表 () 不能省略(即使无参)

lambda原理

本质:编译器生成的仿函数对象

  • Lambda 本身是语法糖,编译后会被转换成一个匿名仿函数类 (重载了 operator() 的类)。
  • 从汇编/机器码层面看,不存在"lambda"这个概念,只有普通的类和函数调用。
  • 这一点和范围 for 很像:范围 for 底层是迭代器,而 lambda 底层是仿函数。

仿函数类的结构映射

Lambda 语法部分 对应仿函数类的结构
捕捉列表 [x, &y] 类的成员变量 (值捕捉 → 成员变量拷贝;引用捕捉 → 成员变量是引用)
参数列表 (int a) operator() 的参数列表
返回值 -> int operator() 的返回值类型
函数体 { ... } operator() 的函数实现

类名与唯一性

  • 编译器会为每个 lambda 生成一个独一无二的类名(按内部规则生成,开发者无法直接写出)。
  • 不同的 lambda(即使签名完全一样)也会生成不同的类,因此 lambda 没有可显式书写的类型,只能用 auto 或模板参数接收。
相关推荐
2401_857918292 小时前
分布式系统安全通信
开发语言·c++·算法
C^h2 小时前
RTthread消息队列学习
开发语言·算法·嵌入式
openallzzz2 小时前
【面经分享】Java实习
java·开发语言
青瓦梦滋2 小时前
Linux进程间通信(IPC)——system V
linux·服务器·c++·文件
鬼蛟2 小时前
Spring Boot
java·开发语言
带鱼吃猫2 小时前
C++11 核心特性解析(一):从初始化列表到移动语义,解锁高效对象构造
开发语言·c++
郝学胜-神的一滴2 小时前
冷却时间下的任务调度最优解:从原理到实现
数据结构·c++·算法·面试
大鹏说大话2 小时前
Java 并发基石:CAS 原理深度解析与 ABA 问题终极解决方案
开发语言·python
啊董dong2 小时前
noi-2026年3月24号作业
数据结构·c++·算法