一、从仿函数到 Lambda:背景理解

在 C++11 之前,我们常常用 仿函数(函数对象) 来实现可调用逻辑,例如:

struct Add {
    int operator()(int a, int b) const {
        return a + b;
    }
};

Add add;
std::cout << add(2, 3);  // 输出 5

这种写法虽然灵活,但需要显式定义一个类。
lambda 表达式 本质上是编译器帮你自动生成一个匿名仿函数类
你只需要一行写法,就能获得同样的功能。


二、Lambda 表达式的基本语法

[capture](parameters) -> return_type {
    // 函数体
};

示例

auto func = [](int a, int b) {
    return a + b;
};
int ans = func(2, 3);  // ans = 5

语法说明

部分含义
[capture]捕获外部变量
(parameters)参数列表
-> return_type返回值类型(可省略)
{...}函数体

三、Lambda 的真实类型是什么?

当你写下:

auto func = [](int a, int b) { return a + b; };

编译器会生成一个匿名类,大致如下:

class __Lambda {
public:
    int operator()(int a, int b) const {
        return a + b;
    }
};
__Lambda func;

也就是说:lambda 是一个编译器生成的匿名类对象。

每个 lambda 都有唯一的类型,通常无法手动命名,所以我们用 auto 接收。


四、捕获外部变量(Capture)

1. 按值捕获 [x]

int x = 10;
auto f = [x]() { std::cout << x; };
f(); // 输出 10

按值捕获会拷贝 x 的当前值进入 lambda。


2. 按引用捕获 [&x]

int x = 10;
auto f = [&x]() { ++x; std::cout << x; };
f();  // 输出 11
std::cout << x; // 输出 11

按引用捕获会让 lambda 访问并修改外部变量。


3. 捕获所有变量

写法含义
[=]按值捕获所有可访问的外部变量
[&]按引用捕获所有可访问的外部变量

也可以混用:

auto f = [a, &b]() { /* a按值,b按引用 */ };

五、Lambda 与 STL 算法

Lambda 在 STL 算法中极其常用,
例如 std::sort 中用于定义自定义排序规则

示例:自定义升降序

bool reverse = true;
std::vector<int> v = {2, 1, 3, 5, 4};

std::sort(v.begin(), v.end(), [reverse](int a, int b) {
    return reverse ? a > b : a < b;
});

如果改成 [&reverse],就能根据外部变量的动态变化改变排序逻辑。


六、Lambda 的 const 性质与 mutable

默认情况下,lambda 的调用运算符 operator()const 的:

auto f = [x]() {
    x++; // ❌ 错误,operator() 默认是 const
};

要让它可修改捕获的拷贝,需要加上 mutable

int x = 10;
auto f = [x]() mutable {
    x++;
    std::cout << x;  // 输出 11
};
f();
std::cout << x;      // 外部的 x 仍是 10
状态是否可修改捕获变量operator() 是否 const
默认
使用 mutable

七、总结与复习要点

知识点关键内容
本质编译器自动生成的匿名仿函数类
捕获方式[x] 按值; [&x] 按引用; [=] / [&] 批量捕获
返回类型自动推导,可用 -> type 指定
const 行为默认 operator() 为 const,可用 mutable 去除
典型用途回调、算法函数、线程任务、延迟执行

结语

Lambda 表达式是现代 C++ 的一项核心特性。
不仅让代码更简洁,也能更灵活地封装局部逻辑。
还能轻松地写出现代风格的 STL 算法、回调函数、线程任务和 GUI 信号槽。


免责声明
本文为个人学习笔记整理,仅供学习交流使用。
如因使用文中代码造成的任何后果,作者并不对此负责。

封面图来源于网络,如有侵权,请联系删除!

更多推荐