Files
Data-Structure/Features-Cpp/C11/lambda函数.MD
2025-08-28 21:17:28 +08:00

139 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 2. Lambda 函数大全
### 2.1 基础概念
* **定义**一种匿名函数对象closure object
* **语法结构**
```cpp
[捕获列表] (参数列表) -> 返回类型 { 函数体 }
```
* **返回类型可省略**:由 `return` 推导。
---
### 2.2 捕获方式
假设外部有 `int a; int b;`
| 捕获方式 | 含义 |
| ----------- | ------------------- |
| `[=]` | 按值捕获所有外部变量(只读) |
| `[&]` | 按引用捕获所有外部变量 |
| `[a]` | 按值捕获变量 `a` |
| `[&a]` | 按引用捕获变量 `a` |
| `[=, &b]` | 默认值捕获,单独指定引用捕获某些变量 |
| `[&, a]` | 默认引用捕获,单独指定按值捕获某些变量 |
| `[this]` | 捕获当前对象指针(隐式捕获成员变量) |
| `[=, this]` | 按值捕获外部变量,同时捕获 this |
---
### 2.3 可变 Lambda (`mutable`)
* 按值捕获默认是 **不可修改捕获变量副本**
* 加 `mutable` 可以修改副本
```cpp
int x = 5;
auto f = [=]() mutable { x += 1; }; // 修改的是副本
```
---
### 2.4 泛型 LambdaC++14+
```cpp
auto add = [](auto a, auto b) { return a + b; };
```
```cpp
C++20
auto add = []<class T>(const T& a, const T& b) { return a + b; };
```
相当于模板函数。
---
### 2.5 返回类型
* **推导**C++14+ 支持多返回类型推导一致性检查)
* **显式声明**
```cpp
auto div = [](double a, double b) -> double { return a/b; };
```
---
### 2.6 存储与调用
* **立即调用**
```cpp
[]{ std::cout << "Hi\n"; }();
```
* **存储到变量**
```cpp
auto f = [](int x){ return x*x; };
std::cout << f(5);
```
---
### 2.7 转换为函数指针
* 仅无捕获 Lambda 可转换:
```cpp
void (*fp)(int) = [](int x){ std::cout << x; };
```
---
### 2.8 在 STL 中用作比较器
```cpp
auto cmp = [](int a, int b) { return a > b; };
std::priority_queue<int, std::vector<int>, decltype(cmp)> pq(cmp);
```
---
## 3. `auto` + Lambda 联合技巧
1. **类型保存**(比较器、回调等):
```cpp
auto cmp = [](int a, int b){ return a < b; };
std::set<int, decltype(cmp)> s(cmp);
```
2. **推导返回类型**(泛型 + `auto`
```cpp
auto combine = [](auto a, auto b) { return a + b; };
```
3. **模板中传 Lambda**
```cpp
template<class F>
void run(F f) { f(); }
run([]{ std::cout << "run!\n"; });
```
4. **`decltype(auto)` 保持引用**
```cpp
auto getter = [](auto& c, size_t i) -> decltype(auto) { return c[i]; };
```
---
如果你愿意,我可以给你画一个 **`auto` 与 Lambda 的知识地图**,把所有用法和推导规则可视化,这样你看一次就能记住。这样对理解捕获机制和类型推导特别直观。
你要我画吗?这样你可以一眼就看全流程。