详解Lambda表达式的捕获
这段代码我之前给你写的例子是对的,我来确认一下其中的关键点,确保你完全理解 ✅
逐行解释
cpp
int count = 0;
auto counter = [count]() mutable {
count++;
return count;
};
[count]—— 值捕获:在 Lambda 定义的那一刻,把count的值(0)拷贝了一份,存在 Lambda 对象内部。mutable—— 默认值捕获的副本是const的,不能修改。加上mutable后,这个副本变得可修改。- 这个副本和外部的
count从此再无关系——是完全独立的两块内存。
调用过程
cpp
counter(); // 内部副本:0 → 1,返回 1 counter(); // 内部副本:1 → 2,返回 2(注意:副本的状态被"记住"了!) count; // 外部的 count 仍是 0
关键点:Lambda 对象内部的 count 副本,在多次调用之间是持续存在的(因为它存储在 Lambda 对象本身里,不是每次调用重新初始化)。所以:
cpp
counter() 第一次调用 → 副本0+1=1 counter() 第二次调用 → 副本1+1=2(基于上次结果累加)
这其实让 counter 变成了一个带状态的计数器,很像一个微型的”闭包对象”。
可视化内存图
定义时:
┌─────────────┐ ┌─────────────┐
│ 外部 count=0 │ │ Lambda对象 │
└─────────────┘ │ 内部副本=0 │ ← mutable,可改
└─────────────┘
调用两次后:
┌─────────────┐ ┌─────────────┐
│ 外部 count=0 │ (不变) │ Lambda对象 │
└─────────────┘ │ 内部副本=2 │ ← 累计变化
└─────────────┘
验证一下:如果不加 mutable 会怎样?
cpp
auto counter = [count]() {
count++; // ❌ 编译错误!
return count;
};
报错大致是:
error: increment of read-only variable 'count'
因为没有 mutable,值捕获的副本默认是 const int count,不允许修改。
这个用法实际有什么用?
cpp
// 生成一个独立计数器,每次调用自增
auto makeCounter = []() {
int id = 0;
return [id]() mutable {
return ++id;
};
};
auto counterA = makeCounter();
auto counterB = makeCounter();
counterA(); // 1
counterA(); // 2
counterB(); // 1(counterB 有自己独立的副本,互不影响!)
这其实就是用 Lambda 实现了一个轻量级的闭包工厂,每个 Lambda 实例都有自己独立的状态。
你的理解完全正确!有什么具体疑问,还是想看更多 mutable 的应用场景?
