✅ 一、Lambda 是什么
一句话:
Lambda 表达式 = 轻量函数(匿名函数)
不需要声明名字、不需要单独写函数体,直接在代码里用。
✳ 二、C++ Lambda 基本格式
C++ 最完整语法:
capture\](parameter_list) mutable noexcept -\> return_type { body }
最常见精简格式:
\[\&\](int x){ return x + 1; }
✳ **三、参数说明**
| 部分 | 含义 |
|--------------------|----------|
| `[capture]` | 捕获外部变量 |
| `(parameter_list)` | 参数列表 |
| `mutable` | 允许修改捕获变量 |
| `return_type` | 返回类型 |
| `{ body }` | 实现代码 |
⚡ **四、捕获(capture)的写法重点**
捕获方式决定 Lambda 能否访问外部变量
例1:按值捕获
int a = 10;
auto f = \[a\]() { return a + 1; };
例2:按引用捕获
int a = 10;
auto f = \[\&a\]() { a++; };
f();
执行后 `a == 11`
例3:全部按值捕获
\[=\]() { ... }
例4:全部按引用捕获
\[\&\]() { ... }
例5:混合捕获
\[=,\&x\](){ ... }
🧰 **五、典型使用场景**
**① 线程回调 / 异步执行**
std::thread t(\[\]{
printf("worker\\n");
});
t.join();
**② STL 回调(最常用)**
std::vector\
类内也隐式捕获 this
但 C++20 允许捕获 this 的副本(防悬垂):
auto f = [*this] { doWork(); };
等于复制整个对象避免悬空指针。
5️⃣ 初始化捕获(C++14+重要能力)
auto f = [val = std::move(bigObj)] {
use(val);
};
变量 val 只存在 Lambda 内
特别适合智能指针:
auto f = [p = std::make_shared<int>(5)] {
std::cout << *p;
};
甚至可以这样:
auto f = [i=0]() mutable {
return ++i;
};
f(); //1
f(); //2
这种行为 = 闭包(closure)状态保持
6️⃣ constexpr Lambda(C++17+)
constexpr auto sqr = [](int x) { return x*x; };
static_assert(sqr(5) == 25);
还能在编译期算 Fibonacci:
constexpr auto fib = [](int n){
if (n <= 1) return n;
return fib(n-1) + fib(n-2);
};
7️⃣ 返回类型显式指定
当需要强制返回类型:
auto f = [](int x) -> double {
if(x > 0) return x;
return 0.5;
};
8️⃣ Lambda + std::function
⚠ 注意性能区别:
std::function<int(int)> f = [](int x){ return x + 1; };
会发生:
-
类型擦除
-
动态分配(可能)
-
低效
推荐保留 auto
auto f = [](int x){ return x+1; };
9️⃣ Lambda 做状态机(闭包)
比如计数器:
auto counter = [i = 0]() mutable {
return ++i;
};
counter(); //1
counter(); //2
counter(); //3
多线程共享状态:
auto sum = [total = std::atomic<int>(0)](int x) mutable {
total += x;
};
这就是函数式闭包的力量。
🔟 Lambda 捕获移动对象
最重要的例子:线程池任务提交
pool.push([task=std::move(task)]() mutable {
task();
});
⭐ 高级技巧加一条:模板 Lambda(C++20)
auto add = []<typename T>(T a, T b){
return a + b;
};
⚙ 底层实现补充
Lambda 本质上:
编译器生成
struct+operator()
带捕获:
int x = 10;
auto f = [x]{ return x+1; };
等价于
struct _lambda {
int x;
int operator()() const { return x+1; }
};
🚩 性能注意点
| 写法 | 性能 |
|---|---|
| auto lambda | 🟢 最快 |
| template lambda | 🟢 最快 |
| std::function | 🔴 可能动态分配,慢 |
| bind | 🔴 更慢/不推荐 |
🧨 STL 中的高阶组合
std::sort(v.begin(), v.end(),
\](auto \&a, auto \&b){ return a.score \> b.score; } ); 过滤: auto it = std::remove_if(v.begin(), v.end(), \[\&\](auto \&n){ return n \< 0; });