Lambda 函数是在 C++11 引入的一种匿名函数,主要用于简化代码、就地定义回调函数 或临时函数。 
语法形式: [capture](parameter_list) -> return_type
 { 
         function_body;
 }; 
 • [capture] 捕获列表 
 o []:不捕获任何变量
 o [=]:以值捕获所有外部变量(拷贝)
 o [&]:以引用捕获所有外部变量 
 o [x]:仅以值捕获变量 x 
 o [&x]:仅以引用捕获变量 x 
 o [=, &y]:默认值捕获,y 使用引用捕获 
 o [&, x]:默认引用捕获,x 使用值捕获 
 • (parameter_list) 参数类似普通函数参数。可以省略,如果没有参数。 
 • -> return_type 返回类型,可以省略,编译器会自动推断(除非返回值复杂)。
 • function_body 函数体,里面写要执行的代码。
 基础示例 
 1. 最简单的 lambda 
 #include <iostream> 
using namespace std; 
int main() { 
auto hello = []() { cout << "Hello Lambda!" << endl; }; 
hello(); 

输出: 
Hello Lambda! 

2. 带参数和返回值 
#include <iostream> 
using namespace std; 
int main() { 
auto add = [](int a, int b) -> int { 
return a + b; 
}; 
cout << add(3, 5) << endl;  // 8 

返回类型 -> int 可以省略,因为编译器能推断。
 
3. 捕获变量(值捕获) 
#include <iostream> 
using namespace std; 
int main() { 
int x = 10; 
auto f = [=]() { 
cout << "x = " << x << endl; 
}; 
f(); 

输出: 
x = 10 
= 表示以值方式捕获变量。

4. 捕获变量(引用捕获) 
#include <iostream> 
using namespace std; 
int main() { 
int x = 10; 
auto f = [&]() { 
x += 5; 
cout << "x = " << x << endl; 
}; 
f(); 
cout << "after f, x = " << x << endl; 

输出: 
x = 15 
after f, x = 15 
& 表示引用捕获,修改会影响外部变量。

5. 混合捕获 
#include <iostream> 
using namespace std; 
int main() { 
int a = 1, b = 2; 
auto f = [=, &b]() { 
// a 按值捕获,不会改变外部 
// b 按引用捕获,可以修改外部 
cout << "inside: a=" << a << " b=" << b << endl; 
// a++; 
b++; 
}; 
f(); 
cout << "outside: a=" << a << " b=" << b << endl; 

输出: 
inside: a=1 b=2 
outside: a=1 b=3


6. 与 STL 算法结合 
#include <iostream> 
#include <vector> 
#include <algorithm> 
using namespace std; 
int main() { 
vector<int> v = {1, 2, 3, 4, 5}; 
// 打印 
for_each(v.begin(), v.end(), [](int x){ 
cout << x << " "; 
}); 
cout << endl; 
// 统计大于 3 的个数 
int count = count_if(v.begin(), v.end(), [](int x){ 
return x > 3; 
}); 
cout << "count > 3: " << count << endl; 

输出: 
1 2 3 4 5  
count > 3: 2

7. 排序自定义比较器 
#include <iostream> 
#include <vector> 
#include <algorithm> 
using namespace std; 
int main() { 
vector<int> v = {5, 2, 9, 1}; 
sort(v.begin(), v.end(), [](int a, int b){ 
return a > b; // 降序 
}); 
for (int x : v) cout << x << " "; 

输出: 
9 5 2 1 

8. 延迟计算(闭包) 
#include <iostream> 
using namespace std; 
int main() { 
int base = 10; 
auto make_adder = [=](int x) { 
return [=](int y) { 
return x + y + base; 
}; 
}; 
auto add5 = make_adder(5);  // base=10, x=5 
cout << add5(3) << endl;    // 18 

9. 作为回调函数 
#include <iostream> 
#include <functional> 
using namespace std; 
void process(int x, function<void(int)> callback) { 
cout << "Processing " << x << endl; 
callback(x); 

int main() { 
process(42, [](int n){ 
cout << "Callback with " << n << endl; 
}); 
}

输出: 
Processing 42 
Callback with 42 
10. 可变 lambda(mutable) 
默认情况下,值捕获的变量在lambda里不能修改,如果要修改,需要 mutable。 
#include <iostream> 
using namespace std; 
int main() { 
int x = 10; 
auto f = [=]() mutable { 
x += 5; 
cout << "inside x=" << x << endl; 
}; 
f(); 
cout << "outside x=" << x << endl; 

输出: 
inside x=15 
outside x=10 
mutable 只影响 lambda内部副本,不会改变外部 x。

总结:
1. 捕获方式: 
o [=] 值捕获 
o [&] 引用捕获 
o [x] 指定变量 
o [=, &y] 混合捕获 
2. 常用场景: 
o STL算法(排序、过滤、计数) 
o 回调函数 
o 封装闭包(延迟计算) 
o 临时小工具函数 
理解 C++ Lambda 的捕获方式,本质上就是搞清楚: 
Lambda 内部函数体如何访问外部作用域的变量。 
Lambda 捕获的本质 
• Lambda 本质上是 一个匿名函数对象(闭包)。 
• 编译器在生成这个对象的时候,会决定: 
o 哪些外部变量需要被带进来(捕获)。 
o 是以值拷贝(复制一个副本),还是 以引用(直接指向原变量)。 
所以 捕获就是决定闭包和外部环境的交互方式。 
捕获方式详解 
1. 不捕获:[] 
• 外部变量一律不能用。 
int a = 10; 
auto f = []() {  
// cout << a; //   
错误,a 未捕获 
}; 
2. 值捕获:[=] 或 [x] 
• 把外部变量复制一份到 Lambda 里。 
• Lambda 内部拿到的是 副本,外部变量不会被修改。 
int a = 10; 
auto f = [=]() {  
cout << "inside: " << a << endl;  
}; 
f(); 
a = 20; 
f(); 
输出: 
inside: 10 
inside: 10 
因为 Lambda 保存的是 a 的拷贝。

3. 引用捕获:[&] 或 [&x] 
• 把外部变量的引用传进来。 
• Lambda 内部和外部变量是同一个。 
int a = 10; 
auto f = [&]() {  
a += 5; 
cout << "inside: " << a << endl;  
}; 
f(); 
cout << "outside: " << a << endl; 
输出: 
inside: 15 
outside: 15 
4. 混合捕获:[=, &x] / [&, x] 
• 可以指定 默认方式,同时给某些变量例外处理。 
int a = 10, b = 20; 
auto f = [=, &b]() { 
// a 按值捕获 
// b 按引用捕获 
cout << "a=" << a << ", b=" << b << endl; 
b += 10; 
}; 
f(); 
cout << "outside: a=" << a << ", b=" << b << endl; 
输出: 
a=10, b=20 
outside: a=10, b=30 
5. 捕获 this 
• 如果在类里面用 Lambda,默认捕获 this 指针。
#include <iostream> 
using namespace std; 
struct Test { 
int x = 42; 
void run() { 
auto f = [=]() { cout << "x=" << x << endl; };  
f(); 

}; 
int main() { 
Test t; 
t.run(); 

输出: 
x=42 
注意:这里 x 并不是直接捕获的,而是通过捕获 this 指针访问到的。 
6. mutable 的值捕获 
默认情况下,值捕获的变量在 Lambda 里是 const 的,如果要修改,需要 mutable。 
int a = 10; 
auto f = [=]() mutable { 
a += 5; // 修改的是副本 
cout << "inside: " << a << endl; 
}; 
f(); 
cout << "outside: " << a << endl; 
输出: 
inside: 15
outside: 10 
一个形象的比喻 
• 值捕获(拷贝):就像拍了一张照片,你带着照片去 Lambda 里看,外面再怎么变,
你手里的照片不会变。 
• 引用捕获(共享):就像把外面的窗户直接打开,Lambda 里看出去和外面看到的
是同一片风景,外面变化你也能看到。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐