匿名函数
认识 Lambda
有些时候,我们可能会需要把函数作为参数进行传递:
int func(std::function<int(int, int)> fn) {
return fn(1, 2);
}
int i_will_pass_this_func(int a, int b) { /* */ }
int i_will_pass_this_func2(int a, int b) { /* */ }
int main() {
func(i_will_pass_this_func);
func(i_will_pass_this_func2);
return 0;
}很显然,在这种情况下,为了传递一个参数而专门定义一个甚至多个完整的函数,显得冗余且复杂。同时,我们还无法灵活地动态改变函数内部的逻辑。
这时候,匿名函数的作用就体现出来了。
Lambda 表达式的定义和使用
C++11 引入了 Lambda 表达式(匿名函数)。Lambda 表达式允许我们在需要的地方直接定义一个匿名函数,并且可以捕获外部变量,使得函数逻辑更加灵活。
Lambda 表达式的基本语法如下:
[捕获列表](参数列表) -> 返回类型 {
// 函数体
}int func(std::function<int(int, int)> f) {
return f(1, 2);
}
int main() {
func([](int a, int b) -> int {
return a + b;
});
// 如果不写返回类型,编译器也会自动推断返回类型
func([](int a, int b) {
return a * b;
});
return 0;
}捕获外部变量
Lambda 表达式的强大之处在于它可以捕获外部变量。例如:
int x = 10, y = 20;
auto add_x = [x, y](int a) {
return a + x + y;
}; // 你也可以把匿名函数赋值给变量,这个变量就可以当函数来使用
std::cout << add_x(5);捕获列表可以指定要捕获哪些变量,以及捕获方式(值捕获或引用捕获)。
[x]:以值捕获变量 x[&x]:以引用捕获变量 x[=]:以值捕获所有外部变量[&]:以引用捕获所有外部变量
应用:Lambda 与标准库算法结合
许多标准库算法都用到了 Lambda 表达式,例如 std::sort 和 std::for_each:
// 想要运行下面的代码,请确保你的项目为 C++23 及以上版本的标准
#include <algorithm> // sort 需要引入这个头文件
#include <print>
int main() {
int arr[] = {4, 2, 1, 3, 5};
std::sort(arr, arr + 5, [](int a, int b) {
return a > b; // 降序排序,a < b 就是升序排序
});
std::for_each(arr, arr+5, [](int n) {
std::println(n);
}); // 遍历整个 arr 并输出所有项。在这里可以使用 for range 来代替
return 0;
}