在 c++++ lambda 表达式中,捕获列表允许捕获外部变量:按值捕获 ([x]):创建局部变量副本,不影响外部变量。按引用捕获 ([&x]):创建对外部变量的引用,修改反映在外部变量中。按引用传递 ([=]):允许修改外部变量,并返回排序后的副本。
C++ Lambda 表达式中的捕获列表详解
在 C++ 中,Lambda 表达式是一种允许您创建匿名函数的对象。捕获列表是 Lambda 表达式的重要组成部分,它指定了从调用环境中捕获的变量。
捕获类型的概要
立即学习“C++免费学习笔记(深入)”;
有三种类型的捕获:
-
按值捕获 ([]):
- 创建局部变量的副本并存储在 Lambda 表达式中。
- 修改副本不会影响外部变量。
-
按引用捕获 ([&]):
- 创建对外部变量的引用。
- 对 Lambda 表达式中的引用进行的更改将反映在外部变量中。
-
按引用传递 ([=]):
- 创建对外部变量的引用,同时允许修改这些变量。
使用捕获列表
在 Lambda 表达式中使用捕获列表时,遵循以下语法:
[capture_list] (parameter_list) -> return_type { body }
以下示例展示了不同类型的捕获:
// 按值捕获
int x = 5;
auto lambda1 = [x] { return x + 1; };
// 按引用捕获
int y = 10;
auto lambda2 = [&y] { y += 1; };
// 按引用传递
int z = 15;
auto lambda3 = [=] { ++z; };
实战案例:排序向量
以下实战案例演示了如何在 Lambda 表达式捕获列表中使用不同类型的捕获:
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {1, 3, 5, 2, 4};
// 按值捕获:使用局部副本 vec1 进行排序
auto lambda1 = [vec1 = vec] (int a, int b) { return a < b; };
std::sort(vec.begin(), vec.end(), lambda1);
// 按引用捕获:修改原始 vec 进行排序
auto lambda2 = [&vec] (int a, int b) { return a > b; };
std::sort(vec.begin(), vec.end(), lambda2);
// 按引用传递:修改原始 vec 并返回排序后的副本
auto lambda3 = [=](int a, int b) { return a < b; };
std::vector<int> vec3 = vec;
std::sort(vec3.begin(), vec3.end(), lambda3);
// 打印结果
for (int i : vec) {
std::cout << i << " ";
}
std::cout << "n";
for (int i : vec3) {
std::cout << i << " ";
}
std::cout << "n";
return 0;
}
输出:
1 2 3 4 5
5 4 3 2 1