在写 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;
});

👉 看起来没问题,但其实有坑🔥

更多推荐