在 C++ 中,Lambda 表达式是一种轻量级的函数对象(或匿名函数),可以在代码中定义并直接使用。它是从 C++11 引入的功能,常用于需要定义短小函数的场景,比如多线程、STL 算法或回调函数中。
1. Lambda 表达式的基本语法
1 2 3
| [捕获列表](参数列表) -> 返回类型 { 函数体 };
|
- **
捕获列表
**:定义 lambda 可以捕获哪些变量,以及如何捕获(按值或按引用)。
- **
参数列表
**:和普通函数类似,定义函数的参数。
- **
返回类型
**:可选,通常由编译器自动推断。
- **
函数体
**:函数的逻辑部分。
2. Lambda 表达式的基本示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <iostream> #include <vector> #include <algorithm>
int main() { auto lambda = [] { std::cout << "Hello, Lambda!" << std::endl; }; lambda();
auto add = [](int a, int b) { return a + b; }; std::cout << "Sum: " << add(5, 3) << std::endl;
return 0; }
|
输出:
3. 捕获列表
Lambda 可以通过 捕获列表 访问外部变量。捕获列表控制外部变量的作用域和捕获方式。
(1) 按值捕获
- Lambda 会复制外部变量的值。
- 外部变量的值在 Lambda 定义时捕获,不受后续修改影响。
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include <iostream>
int main() { int x = 10; auto byValue = [x] { std::cout << "Captured by value: " << x << std::endl; };
x = 20; byValue();
return 0; }
|
输出:
(2) 按引用捕获
- Lambda 捕获外部变量的引用,因此可以修改外部变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <iostream>
int main() { int x = 10; auto byReference = [&x] { x += 10; std::cout << "Captured by reference: " << x << std::endl; };
byReference(); std::cout << "Modified x: " << x << std::endl;
return 0; }
|
输出:
1 2
| Captured by reference: 20 Modified x: 20
|
(3) 捕获所有变量
- 按值捕获所有变量:使用
[=]
。
- 按引用捕获所有变量:使用
[&]
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| #include <iostream>
int main() { int x = 10, y = 20;
auto captureAllByValue = [=] { std::cout << "x: " << x << ", y: " << y << std::endl; };
auto captureAllByReference = [&] { x += 5; y += 5; std::cout << "Modified x: " << x << ", y: " << y << std::endl; };
captureAllByValue(); captureAllByReference();
return 0; }
|
输出:
1 2
| x: 10, y: 20 Modified x: 15, y: 25
|
4. Lambda 的返回类型
(1) 自动推断返回类型
- 如果函数体只有一条
return
语句,返回类型会自动推断。1 2 3
| auto multiply = [](int a, int b) { return a * b; };
|
(2) 显式指定返回类型
- 如果返回类型不能自动推断,可以显式指定。
1 2 3
| auto divide = [](int a, int b) -> double { return (double)a / b; };
|
5. Lambda 在 STL 中的使用
Lambda 通常用作回调函数,尤其在 STL 算法中非常常见。
(1) 用于 std::sort
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| #include <iostream> #include <vector> #include <algorithm>
int main() { std::vector<int> nums = {5, 2, 8, 1, 3};
std::sort(nums.begin(), nums.end(), [](int a, int b) { return a > b; });
for (int num : nums) { std::cout << num << " "; }
return 0; }
|
输出:
(2) 用于 std::for_each
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <iostream> #include <vector> #include <algorithm>
int main() { std::vector<int> nums = {1, 2, 3, 4, 5};
std::for_each(nums.begin(), nums.end(), [](int num) { std::cout << num << " "; });
return 0; }
|
输出:
6. 带状态的 Lambda
- Lambda 本质是一个函数对象,因此它可以存储状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <iostream>
int main() { int counter = 0;
auto increment = [counter]() mutable { return ++counter; };
std::cout << increment() << std::endl; std::cout << increment() << std::endl;
return 0; }
|
输出:
总结
- Lambda 表达式是一种简洁的方式定义匿名函数,非常适合短小的逻辑。
- 捕获列表允许访问外部变量,通过值或引用捕获,甚至可以捕获所有变量。
- 在现代 C++ 中,Lambda 经常用于 STL 算法、多线程、回调等场景,是高效编写代码的重要工具。