C++的lambda表达式
在 C++ 中,lambda 表达式(或匿名函数)是一种简洁的方式来定义函数对象或小型的临时函数。它引入于 C++11,并在 C++14 和 C++17 中得到了进一步扩展。Lambda 表达式的主要特点是能够在函数中内联定义临时逻辑,而无需显式声明一个函数。
基本语法
C++ 的 lambda 表达式的一般形式是:
1 |
|
[capture]
:捕获列表,用于指定 lambda 如何访问其外部作用域中的变量。(parameters)
:参数列表,类似普通函数的参数列表。-> return_type
(可选):返回值类型。如果可以自动推断返回类型,则可以省略。{ body }
:函数体,包含要执行的逻辑。
简单示例
以下是一个简单的 lambda 表达式示例:
1 |
|
输出:
1 |
|
捕获列表([capture]
)
捕获列表定义了 lambda 如何访问外部变量。常见的捕获方式包括:
-
按值捕获(
[x]
):
将外部变量的值拷贝到 lambda 中。lambda 内的修改不会影响外部变量。1
2
3
4
5int x = 10;
auto f = [x]() { std::cout << x << std::endl; };
f(); // 输出 10
x = 20; // 修改外部的 x
f(); // 仍然输出 10(lambda 内的 x 是拷贝) -
按引用捕获(
[&x]
):
lambda 捕获的是变量的引用,lambda 内对变量的修改会影响外部变量。1
2
3
4int x = 10;
auto f = [&x]() { x += 5; };
f(); // 修改了外部的 x
std::cout << x << std::endl; // 输出 15 -
捕获全部变量:
[=]
:按值捕获所有外部变量。[&]
:按引用捕获所有外部变量。
1
2
3int a = 5, b = 10;
auto lambda1 = [=]() { return a + b; }; // 按值捕获
auto lambda2 = [&]() { b += a; }; // 按引用捕获 -
混合捕获:
捕获特定变量,同时按值或引用捕获其他变量。1
2int a = 5, b = 10;
auto lambda = [a, &b]() { b += a; }; // a 按值捕获,b 按引用捕获
返回值
C++11 中,lambda 的返回值通常是自动推断的:
1 |
|
如果返回值类型不一致,编译器则会报错。
如果返回类型复杂或需要显式指定,可以使用 -> return_type
:
1 |
|
Lambda 表达式的实际用途
-
排序
使用 lambda 定义自定义的排序逻辑:1
2
3
4std::vector<int> nums = {5, 2, 8, 1};
std::sort(nums.begin(), nums.end(), [](int a, int b) {
return a > b; // 按降序排序
}); -
过滤
使用 lambda 筛选元素:1
2
3
4std::vector<int> nums = {1, 2, 3, 4, 5};
nums.erase(std::remove_if(nums.begin(), nums.end(), [](int x) {
return x % 2 == 0; // 移除所有偶数
}), nums.end()); -
异步操作
使用 lambda 编写回调函数:1
2
3
4
5
6
7
8
9
10#include <thread>
#include <iostream>
int main() {
std::thread t([]() {
std::cout << "Hello from lambda in a thread!" << std::endl;
});
t.join();
return 0;
}
注意事项
-
捕获列表的生命周期:
捕获的变量按值或按引用会影响它的生命周期:- 按值捕获是拷贝,原变量的修改不会影响捕获的值。
- 按引用捕获需要确保变量在 lambda 的生命周期内仍然有效。
-
可变 lambda:
默认情况下,当lambda使用按值捕获([x]
)时,是不可修改捕获的值的:1
2
3int x = 10;
auto lambda = [x]() { x += 5; std::cout << x << std::endl; }; // 这里会报错:表达式必须是可修改的左值如果需要修改捕获的值,可以用
mutable
关键字,mutable
允许修改捕获的副本(注意,是副本,不是原来的x
)1
2
3
4int x = 10;
auto lambda = [x]() mutable { x += 5; std::cout << x << std::endl; };
lambda(); // 输出 15
std::cout << x << std::endl; // 原来的 x 仍然是 10 -
嵌套 lambda:
Lambda 表达式可以嵌套使用:1
2
3
4
5
6auto outer = [](int x) {
return [x](int y) { return x + y; };
};
auto inner = outer(10);
std::cout << inner(5) << std::endl; // 输出 15
总结
Lambda 表达式使得 C++ 更加灵活,尤其是在需要传递临时函数或函数对象的场景中(例如排序、回调等)。使用它可以大大减少代码的冗余,提高代码的可读性和可维护性。
C++的lambda表达式
https://blog.supersource.top/lambda_in_cpp/