c++ lambda表达式是什么 匿名函数的语法和使用【详解】

9次阅读

C++ lambda 表达式是编译器生成的闭包对象,支持捕获外部变量,基本语法为[捕获列表](参数列表) mutable 异常说明 属性说明 -> 返回类型 {函数体},最简形式为[]{};常用捕获方式包括[]、[x]、[&x]、[=]、[&]、[=, &z]、[this];返回类型通常自动推导;广泛用于 STL 算法、回调、状态封装等场景。

c++ lambda 表达式是什么 匿名函数的语法和使用【详解】

C++ lambda 表达式是一种定义匿名函数对象的简洁语法,它能在需要函数对象的地方就地创建、使用,无需单独命名或声明函数。 它不是传统意义上的“函数”,而是一个编译器自动生成的闭包类型(closure type)的对象,支持捕获外部 作用域 的变量,是现代 C ++ 中函数式编程和 STL 算法配合的核心 工具 之一。

lambda 的基本语法结构

一个 lambda 表达式的完整形式为:

[capture-list](parameter-list) mutable-specifier exception-specifier attribute-specifier -> return-type {body}

其中大多数部分可省略,最简形式可以只有[]{}(空捕获、无参、无返回值、空函数体)。常用简化写法如下:

  • []() {/* 无捕获、无参 */} —— 最简 lambda
  • [x, &y](int a) mutable {return a + x + y;} —— 捕获局部变量 x(值)、y(引用),接受 int 参数,允许修改内部副本(mutable),有返回值
  • [&](auto… args) {/* 捕获所有外部变量按引用 */} —— C++14 起支持泛型 lambda 和广义捕获

捕获列表(capture list)怎么用

捕获列表决定 lambda 如何访问定义时所在作用域的变量,是 lambda区别 于普通函数的关键:

立即学习C++ 免费学习笔记(深入)”;

  • []:不捕获任何变量
  • [x, y]:以值方式拷贝 x、y(进入 lambda 时复制一份)
  • [&x, &y]:以引用方式绑定 x、y(修改会影响原变量)
  • [=]:默认值捕获,等价于自动把所有在 lambda 体内被使用的自动变量以值方式捕获
  • [&]:默认引用捕获,所有被使用的自动变量都按引用捕获
  • [=, &z]:默认值捕获,但 z 显式按引用捕获(混合捕获)
  • [this]:捕获当前对象的指针(在类成员函数中访问 this->成员)

⚠️ 注意:捕获的变量生命周期必须长于 lambda 对象本身;若按引用捕获局部变量,而 lambda 后续被保存(如存入 vector 或跨线程调用),可能导致悬垂引用——这是常见错误来源。

返回类型与自动推导

多数情况下不必显式写返回类型:

  • 单条 return 语句且无 return void,编译器自动推导(如[](int x) {return x * 2;} 推导为int
  • 多条 return 语句或含条件分支,需满足所有分支返回同类型,否则编译失败
  • 含 void 表达式(如cout)或无 return,返回类型为 void
  • 强制指定返回类型用尾置返回语法:[](int x) -> double {return x * 1.5;}

典型应用场景

lambda 真正价值在于“即写即用”,尤其适合以下情况:

  • 配合 STL 算法:如std::sort(v.begin(), v.end(), [](int a, int b) {return a> b; });
  • 作为 回调函数 :传给std::threadstd::async 或 GUI 事件系统
  • 封装短小逻辑避免命名污染:比如在循环内定义一次性的比较 / 转换逻辑
  • 实现闭包行为:捕获并携带状态,例如计数器、配置参数等

例如,创建一个带初始偏移的加法器:

auto adder = [offset = 10](int x) {return x + offset;};
int res = adder(5); // 得到 15

这里 offset = 10 是 C ++14 引入的初始化捕获,让 lambda 自带初始化状态,比手动写 functor 更轻量。

text=ZqhQzanResources