C++ Lambda 表达式详解
Lambda 表达式是 C++11 引入的一项重要特性,它允许在代码中内联定义匿名函数对象。Lambda 极大地简化了代码编写,特别是在使用 STL 算法时。
基本语法
Lambda 表达式的基本语法如下:
[捕获列表](参数列表) -> 返回类型 { 函数体 }
其中:
-
捕获列表
:定义 lambda 表达式可以访问的外部变量 -
参数列表
:与普通函数的参数列表类似 -
返回类型
:可以省略,编译器会自动推导 -
函数体
:包含 lambda 表达式的执行代码
捕获列表详解
捕获列表决定了 lambda 表达式如何访问外部变量:
-
值捕获
[=]
或[var]
int x = 10; auto lambda = [x] { return x; }; // 捕获x的值
-
引用捕获
[&]
或[&var]
int y = 20; auto lambda = [&y] { y++; }; // 捕获y的引用
-
混合捕获
int a = 1, b = 2; auto lambda = [a, &b] { return a + b; }; // a值捕获,b引用捕获
-
隐式捕获
[=] // 所有变量值捕获 [&] // 所有变量引用捕获 [=, &var] // 除var外值捕获,var引用捕获 [&, var] // 除var外引用捕获,var值捕获
参数列表
与普通函数类似,但有以下特点:
-
可以省略参数列表(如果没有参数)
-
支持 auto 参数(C++14 起)
-
支持可变参数模板
auto lambda1 = [] { return 42; }; // 无参数
auto lambda2 = [](int a, int b) { return a + b; }; // 带参数
auto lambda3 = [](auto x, auto y) { return x * y; }; // C++14 auto参数
返回类型
返回类型可以显式指定,也可以由编译器自动推导:
auto lambda1 = [] { return 42; }; // 返回类型推导为int
auto lambda2 = []() -> double { return 3.14; }; // 显式指定返回类型
当函数体中有多个 return 语句且返回类型不一致时,必须显式指定返回类型。
mutable 关键字
默认情况下,值捕获的变量在 lambda 内是 const 的。使用 mutable 可以修改这些副本:
int x = 10;
auto lambda = [x]() mutable { x++; return x; };
// x的副本被修改,但外部的x不变
示例代码
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// 简单lambda示例
auto greet = [] { std::cout << "Hello, Lambda!\n"; };
greet();
// 带参数的lambda
auto add = [](int a, int b) { return a + b; };
std::cout << "5 + 3 = " << add(5, 3) << "\n";
// 在STL算法中使用lambda
std::vector<int> nums = {1, 2, 3, 4, 5};
std::for_each(nums.begin(), nums.end(), [](int n) {
std::cout << n << " ";
});
std::cout << "\n";
// 捕获局部变量
int factor = 2;
auto multiply = [factor](int n) { return n * factor; };
std::transform(nums.begin(), nums.end(), nums.begin(), multiply);
// 引用捕获修改外部变量
int sum = 0;
std::for_each(nums.begin(), nums.end(), [&sum](int n) { sum += n; });
std::cout << "Sum: " << sum << "\n";
// mutable示例
int counter = 0;
auto increment = [counter]() mutable { return ++counter; };
increment();
increment();
std::cout << "Counter inside lambda: " << increment() << "\n";
std::cout << "Counter outside: " << counter << "\n";
return 0;
}
高级用法
-
泛型 lambda (C++14):
auto generic_lambda = [](auto x, auto y) { return x + y; };
-
模板 lambda (C++20):
auto template_lambda = []<typename T>(T x, T y) { return x * y; };
-
立即调用 lambda:
const int result = [](int x) { return x * x; }(5); // 结果是25
-
作为函数参数传递:
void process(const std::function<void(int)>& f) { f(42); } process([](int x) { std::cout << x << "\n"; });
Lambda 表达式是现代 C++ 编程中非常强大的工具,合理使用可以大大简化代码并提高可读性。