Lambda表达式是C++11引入的匿名函数机制,语法为捕获列表 mutable noexcept -> 返回类型 {函数体},常用部分为捕获列表、参数列表和函数体;捕获列表控制对外部变量的访问方式,如[x]值捕获、[&y]引用捕获、[=]值捕获所有、[&]引用捕获所有;参数列表支持auto类型推导(C++14起);mutable允许修改值捕获的副本;返回类型可自动推导;常用于STL算法如std::sort([x](int a, int b){return a > b;})实现降序排序,或封装局部逻辑如[rate](double price){return price * rate;}避免定义额外函数。

Lambda表达式是C++11引入的重要特性,它允许你在需要函数对象的地方直接定义匿名函数,无需提前声明独立的函数或函数对象类。这种机制让代码更简洁、直观,尤其在配合STL算法时非常高效。
基本语法结构
一个Lambda表达式的完整语法如下:
[捕获列表] (参数列表) mutable noexcept -> 返回类型 { 函数体 }其中,最常用的部分是捕获列表、参数列表和函数体,其他部分可根据需要省略。
- 捕获列表:决定如何访问外部作用域中的变量,如 [x] 值捕获x,[&y] 引用捕获y,[=] 值捕获所有外部变量,[&] 引用捕获所有外部变量。
- 参数列表:与普通函数参数类似,可为空 ()。支持自动类型推导(使用auto,需C++14以上)。
- mutable:默认值捕获的变量在Lambda内不可修改,加上mutable后可修改副本。
- 返回类型:若函数体只有一条return语句,编译器可自动推导返回类型,此时可省略 -> 返回类型部分。
简单示例:
立即学习“C++免费学习笔记(深入)”;
int x = 10;auto f = [x](int n) -> int { return x + n; };
std::cout
常见使用场景
Lambda最常用于替代函数指针或仿函数,提升代码可读性和开发效率。
1. 配合STL算法使用
例如对容器元素排序、查找、遍历等操作中自定义逻辑:
std::vectorstd::sort(nums.begin(), nums.end(), [](int a, int b) {
return a > b;
}); // 降序排序
2. 封装局部逻辑
当某个小功能只在局部使用时,用Lambda避免定义额外函数:
double rate = 1.1;auto applyTax = [rate](double price) { return price * rate; };
std::cout
3. 延迟执行或回调函数
Lambda可保存为std::function对象,在事件处理或异步任务中作为回调:
#includestd::function
int count = 0;
callback = [&count]() { count++; };
callback(); // 执行一次,count变为1
捕获方式详解
捕获决定了Lambda如何访问外部变量,选择不当可能导致未定义行为或逻辑错误。
- [=]:按值复制外部变量,Lambda内部使用的是副本,不会影响原变量。
- [&]:按引用捕获,Lambda中修改会影响原变量,注意生命周期问题——确保外部变量在Lambda调用时仍有效。
- [this]:捕获当前对象的this指针,可用于成员函数内的Lambda访问成员变量。
- 混合捕获:C++14支持混合写法,如 [=, &var] 表示默认值捕获,但var用引用捕获。
典型陷阱:
std::function{
int temp = 42;
dangerous = [&temp]() { return temp; }; // 引用悬空!
} // temp已销毁
// dangerous(); // 调用将导致未定义行为
总结
Lambda表达式极大增强了C++的表达能力,特别是在算法定制、闭包封装和回调机制中表现突出。掌握其语法细节和捕获规则,能写出更清晰、高效的现代C++代码。合理使用,避免引用捕获带来的生命周期问题,基本上就这些。









