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 或模板参数接收。
相关推荐
未来之窗软件服务17 分钟前
计算机二级[英文]-C 字符串移动—东方仙盟
c语言·开发语言·仙盟创梦ide·东方仙盟
Wang's Blog19 分钟前
Java框架快速入门: Spring Security+OAuth2之过滤器与过滤器链
java·开发语言·spring
谢尔登39 分钟前
01_Java基础速通
java·开发语言
前端炒粉40 分钟前
DOM 常用 API 速查表
开发语言·javascript·ecmascript
小七在进步2 小时前
C++入门(2)
java·jvm·c++
en.en..2 小时前
C语言核心解析:#define与typedef本质区别
开发语言·c++·算法
2601_966949652 小时前
批量获取多只股票五档盘口的极简方案:QuantDash Python SDK 实战指南
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
码匠许师傅2 小时前
【设计模式精讲】26.策略模式(Strategy)
c++·设计模式·策略模式·uml
点心的游戏开发世界3 小时前
GDScript 入门笔记:目录
开发语言·笔记·游戏引擎·godot
洋不写bug3 小时前
二叉树(二) 常见基础操作解析|结点数、树高、查找结点、判断完全二叉树
java·开发语言·数据结构·完全二叉树·二叉树结点数·树高·查找结点