lambda
Lambda 表达式是 C++11 引入的一种简洁的方式,用来定义匿名函数,也就是没有名字的函数。它们可以在代码中定义并立即使用,常常用于需要临时函数的场景,比如回调、并发任务等。Lambda 表达式让代码更紧凑,也更容易传递函数行为。
Lambda 表达式的语法
[capture](parameters) -> return_type
{
// function body
};
- capture:捕获列表,指定 lambda 表达式如何捕获外部作用域中的变量。
- parameters:参数列表,与普通函数的参数列表类似。
- return_type:返回类型,如果省略,编译器会自动推导(C++14 之后可以省略)。
- function body:函数体,包含 lambda 表达式的具体逻辑。
1. 捕获列表 [capture]
捕获列表用于指定 lambda 表达式如何访问其外部作用域的变量。常见的捕获方式有:
- [ ]:不捕获任何外部变量。
- [=]:以值捕获方式(拷贝)捕获外部作用域的所有变量。
- [&]:以引用捕获方式捕获外部作用域的所有变量。
- [x]:值捕获变量 x。
- [&x]:引用捕获变量 x。
- [=, &x]:以值捕获所有变量,但 x 以引用捕获。
- [&, x]:以引用捕获所有变量,但 x 以值捕获。
2. 参数列表 (parameters)
参数列表与普通函数的参数列表类似。它定义了 lambda 表达式可以接受的参数。
3. 返回类型 -> return_type
返回类型可以省略,编译器会自动推导。如果有复杂的返回类型,可以显式指定。省略时,编译器会根据 return 语句来推导返回类型。
4. 函数体 { function body }
函数体是 lambda 表达式的核心逻辑部分,与普通函数的函数体类似。
例子
例子 1:简单的 Lambda 表达式
#include <iostream>
int main() {
auto greet = []()
{
std::cout << "Hello, World!" << std::endl;
};
greet(); // 调用 lambda 表达式
return 0;
}
例子 2:捕获外部变量
#include <iostream>
int main()
{
int a = 10;
int b = 20;
auto sum = [a, b]()
{
return a + b;
};
std::cout << "Sum: " << sum() << std::endl; // 输出 Sum: 30
return 0;
}
例子 3:引用捕获
#include <iostream>
int main()
{
int counter = 0;
auto increment = [&counter]()
{
++counter;
};
increment();
increment();
std::cout << "Counter: " << counter << std::endl; // 输出 Counter: 2
return 0;
}
例子 4:有参数的 Lambda 表达式
#include <iostream>
int main()
{
auto multiply = [](int x, int y) -> int
{
return x * y;
};
std::cout << "Product: " << multiply(5, 3) << std::endl; // 输出 Product: 15
return 0;
}
例子 5:在 STL 算法中使用 Lambda 表达式
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
std::vector<int> numbers = {5, 3, 1, 4, 2};
std::sort(numbers.begin(), numbers.end(), [](int a, int b)
{
return a < b;
});
for (int num : numbers)
{
std::cout << num << " "; // 输出 1 2 3 4 5
}
std::cout << std::endl;
return 0;
}
总结
Lambda 表达式是 C++ 中非常强大和灵活的功能,允许在需要时定义小型匿名函数,特别适用于回调、并发操作和 STL 算法中。它们使代码更简洁,更易于维护。