C++:Lambda表达式
-
-
- C++中`lambda`的基本语法
- [1. 捕获列表(Capture List)](#1. 捕获列表(Capture List))
- [2. 示例代码](#2. 示例代码)
-
- [示例 1:简单的`lambda`](#示例 1:简单的
lambda
) - [示例 2:捕获变量](#示例 2:捕获变量)
- [示例 3:按引用捕获](#示例 3:按引用捕获)
- [示例 4:捕获所有变量](#示例 4:捕获所有变量)
- [示例 5:作为函数参数](#示例 5:作为函数参数)
- [示例 1:简单的`lambda`](#示例 1:简单的
- [3. `lambda`的高级特性](#3.
lambda
的高级特性) - [4. 适用场景](#4. 适用场景)
- [5. 注意事项](#5. 注意事项)
- 总结
-
在C++中,lambda
表达式是一种强大的特性,用于创建匿名函数对象。它从C++11标准开始引入,并在后续版本中不断完善。lambda
表达式在C++中广泛应用于标准库算法(如std::sort
、std::for_each
等)以及其他需要函数对象的场景。
代码链接:https://gitee.com/hu_yuchen/C++11/lambda
C++中lambda
的基本语法
C++的lambda
表达式语法如下:
cpp
[capture](parameters) -> return_type { body }
capture
:捕获列表,用于捕获当前作用域中的变量。parameters
:参数列表,类似于普通函数的参数。-> return_type
:返回类型(可选)。如果不指定,编译器会自动推导返回类型。body
:函数体,包含具体的逻辑。
1. 捕获列表(Capture List)
捕获列表用于将当前作用域中的变量捕获到lambda
表达式中。捕获方式有以下几种:
- 按值捕获:使用
[x]
捕获变量x
的副本。 - 按引用捕获:使用
[&x]
捕获变量x
的引用。 - 捕获所有变量:使用
[=]
按值捕获当前作用域中所有变量。 - 捕获所有变量的引用:使用
[&]
按引用捕获当前作用域中所有变量。 - 混合捕获:可以同时使用按值和按引用捕获,例如
[x, &y]
。
2. 示例代码
以下是一些C++中lambda
表达式的典型用法:
示例 1:简单的lambda
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用 lambda 表达式作为回调函数
std::for_each(vec.begin(), vec.end(), [](int x) {
std::cout << x << " ";
});
std::cout << std::endl;
return 0;
}
输出:
1 2 3 4 5
示例 2:捕获变量
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
int factor = 2;
std::vector<int> vec = {1, 2, 3, 4, 5};
// 按值捕获变量 factor
std::for_each(vec.begin(), vec.end(), [factor](int x) {
std::cout << x * factor << " ";
});
std::cout << std::endl;
return 0;
}
输出:
2 4 6 8 10
示例 3:按引用捕获
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
int factor = 2;
std::vector<int> vec = {1, 2, 3, 4, 5};
// 按引用捕获变量 factor
std::for_each(vec.begin(), vec.end(), [&factor](int x) {
std::cout << x * factor << " ";
factor++; // 修改捕获的变量
});
std::cout << std::endl;
std::cout << "Final value of factor: " << factor << std::endl;
return 0;
}
输出:
2 6 12 20 30
Final value of factor: 7
示例 4:捕获所有变量
cpp
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
int a = 2;
int b = 3;
// 捕获所有变量
auto lambda = [=](){ return a * b; };
std::cout << "Result: " << lambda() << std::endl;
return 0;
}
输出:
Result: 6
示例 5:作为函数参数
cpp
#include <iostream>
#include <vector>
#include <algorithm>
void processVector(const std::vector<int>& vec, void (*func)(int)) {
for (int x : vec) {
func(x);
}
}
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用 lambda 表达式作为函数参数
processVector(vec, [](int x) {
std::cout << x * x << " ";
});
std::cout << std::endl;
return 0;
}
输出:
1 4 9 16 25
3. lambda
的高级特性
-
可调用对象:
lambda
表达式本质上是一个可调用对象,可以赋值给std::function
或其他支持函数调用的类型。 -
默认捕获模式:可以指定默认捕获模式,例如
[=, &x]
表示按值捕获所有变量,但x
按引用捕获。 -
mutable
关键字:如果lambda
需要修改捕获的变量,可以在lambda
表达式中使用mutable
关键字。cppauto lambda = [x = 5]() mutable { x++; std::cout << x << std::endl; }; lambda(); // 输出 6
4. 适用场景
- 标准库算法:如
std::sort
、std::for_each
、std::transform
等,lambda
表达式可以作为回调函数传递。 - 线程创建:在
std::thread
中,可以使用lambda
表达式作为线程函数。 - 事件处理:在GUI编程或事件驱动的场景中,
lambda
表达式可以作为事件处理器。 - 简化代码:对于简单的函数逻辑,
lambda
可以减少代码量,使代码更简洁。
5. 注意事项
- 捕获变量的生命周期:如果捕获了局部变量的引用,需要确保
lambda
表达式在变量生命周期内使用,否则可能导致未定义行为。 - 性能开销:虽然
lambda
表达式通常不会引入额外的性能开销,但捕获大量变量可能会增加内存使用。 - 复杂逻辑:对于复杂的逻辑,建议使用普通函数而不是
lambda
表达式,以提高代码的可读性。
总结
C++中的lambda
表达式是一种非常灵活和强大的特性,适用于需要简单函数对象的场景。通过合理使用捕获列表和参数列表,可以实现简洁高效的代码。