从 0 开始讲透 C++ Lambda(对标 Java)
·
在写 C++ 多线程或 STL 时,经常会看到这样的代码:
std::thread t([]{
std::cout << "Hello C++ Thread\n";
});
很多人第一反应:
这 [] 是什么?为什么和 Java 不一样?
一、先给结论(先建立整体认知🔥)
C++ lambda = 一个“匿名函数对象”(不是普通函数)
👉 对标 Java:
Java: () -> {}
C++ : []() {}
👉 最大区别:
C++ 多了一个 [](捕获外部变量)
二、lambda 到底是什么?
最简单理解
[] {
std::cout << "Hello\n";
}
就是:一个没有名字的函数
等价普通函数
void func() {
std::cout << "Hello\n";
}
区别:
lambda 可以“现场写”,不用起名字
三、完整结构(必须掌握)
[capture](params) { body }
各部分含义
| 部分 | 作用 |
|---|---|
[] | 捕获外部变量(C++特有🔥) |
() | 参数(和函数一样) |
{} | 函数体 |
四、params 是什么?
👉 就是普通函数参数👇
[](int x) {
std::cout << x;
}
👉 调用:
auto f = [](int x) {
std::cout << x;
};
f(10);
👉 对标 Java:
(x) -> System.out.println(x);
五、capture 是什么?(核心区别)
👉 capture 用来解决一个问题:
函数内部能不能用外部变量?
❌ 不写 capture
int a = 10;
auto f = [] {
std::cout << a; // ❌ 编译报错
};
✅ 正确写法
auto f = [a] {
std::cout << a;
};
👉 含义:
把 a 拷贝进 lambda
六、capture 常用写法(记这几个就够)
[] 不捕获
[a] 值捕获
[&a] 引用捕获
[=] 全部值捕获
[&] 全部引用捕获
七、capture vs params(很多人会混)
一句话区分
capture = 外部变量(上下文)
params = 调用参数(输入)
示例
int a = 10;
auto f = [a](int x) {
return a + x;
};
👉 含义:
a → 外部带进来
x → 调用时传进来
八、为什么 C++ 比 Java 多一个 []?
Java
int a = 10;
Runnable r = () -> {
System.out.println(a);
};
👉 Java 默认可以使用外部变量(但必须 final)
C++
int a = 10;
auto f = [] {
std::cout << a; // ❌
};
👉 C++ 默认:
不能访问外部变量
👉 必须显式声明:
[a] { ... }
👉 设计原因:更明确控制变量生命周期和拷贝方式
九、lambda 本质是什么?(关键突破)
👉 lambda 不是函数,而是:
一个类(对象)
等价写法👇
auto f = [] {
std::cout << "Hello\n";
};
👉 实际类似:
struct Lambda {
void operator()() const {
std::cout << "Hello\n";
}
};
👉 所以: f(); // 调用 operator()
👉 这叫:
函数对象(functor)
十、为什么 thread / STL 都能用 lambda?
因为:
lambda = 可调用对象
👉 所以可以传给:
std::thread
std::sort
std::for_each
示例
std::sort(v.begin(), v.end(), [](int a, int b) {
return a < b;
});
十一、总结(笔记版🔥)
C++ lambda:
[capture](params) { body }
本质:
- 匿名函数对象(类)
- 重载 operator()
capture:
- 外部变量
- 控制拷贝 or 引用
params:
- 函数参数
区别:
capture = 外部上下文
params = 输入参数
对比 Java:
Java: () -> {}
C++ : []() {}(多了捕获)
十二、你现在掌握了什么(非常关键🔥)
你已经打通:
✔ lambda结构
✔ capture机制
✔ params
✔ 与Java对比
✔ 本质(类 + operator())
👉 这意味着你已经进入:
现代 C++(并发 + STL + 回调)核心能力区🔥
下一篇:
👉 《C++ Lambda 进阶:为什么 [&] 在线程中会出问题?》
这个是面试高频 + 工程坑👇
int a = 10;
std::thread t([&]{
std::cout << a;
});
👉 看起来没问题,但其实有坑🔥
更多推荐
所有评论(0)