C++ Lambda表达式使用
Lambda 表达式基本语法
C++ Lambda 表达式的基本结构如下:
[capture](parameters) -> return_type { body }[capture]:捕获列表,指定外部变量的捕获方式(值捕获、引用捕获等)。(parameters):参数列表,与普通函数参数一致(C++14 支持auto泛型参数)。-> return_type:可选的返回类型声明(省略时由编译器自动推导)。{ body }:函数体,实现具体逻辑。
最小 Lambda 示例:
auto print = [] { std::cout << "Hello, Lambda!"; }; print(); // 输出:Hello, Lambda!捕获列表的用法
捕获列表控制 Lambda 访问外部变量的方式:
值捕获(复制变量):
int x = 10; auto lambda = [x] { return x + 1; }; // 捕获 x 的副本引用捕获(直接操作原变量):
int y = 20; auto lambda = [&y] { y += 5; }; // 修改原变量 y lambda(); // y 变为 25混合捕获:
int a = 1, b = 2; auto lambda = [a, &b] { return a + b; }; // a 值捕获,b 引用捕获隐式捕获:
[=]:以值捕获所有外部变量。[&]:以引用捕获所有外部变量。[=, &x]:默认值捕获,仅x引用捕获。
与 STL 算法结合
Lambda 常用于简化 STL 算法的调用,例如std::sort或std::for_each:
std::vector<int> nums = {3, 1, 4, 1, 5}; std::sort(nums.begin(), nums.end(), [](int a, int b) { return a > b; }); // nums 变为 {5, 4, 3, 1, 1}生命周期与悬垂引用风险
若 Lambda 捕获引用且原始变量已销毁,后续调用会引发未定义行为:
std::function<int()> createLambda() { int z = 30; return [&z] { return z; }; // 危险:z 是局部变量 } auto f = createLambda(); f(); // 错误:z 已销毁性能优化建议
- 优先使用
auto存储 Lambda:避免std::function的间接调用开销。 - 无捕获 Lambda 可转换为函数指针:适用于 C 接口回调。
- 避免过度捕获:仅捕获必要变量以减少对象大小。
高级特性(C++14/17)
泛型 Lambda(C++14):
auto adder = [](auto a, auto b) { return a + b; }; adder(3, 4.5); // 返回 7.5初始化捕获(C++14):
int x = 10; auto lambda = [y = x + 1] { return y; }; // y 初始化为 x + 1constexprLambda(C++17):
constexpr auto square = [](int n) { return n * n; }; static_assert(square(5) == 25); // 编译期计算