C++ 学习()——lambda
lambda 表达式详解
在现代 C++(从 C++11 起)中,lambda 表达式(又称匿名函数)是一种极大增强代码简洁性和灵活性的语法结构。它允许你直接在代码中定义可调用对象,无需事先命名函数。无论是在多线程、STL 算法、事件处理,还是回调函数场景中,lambda 都是利器。
本篇将带你系统了解 C++ 中 lambda 的定义、语法、捕获方式、应用场景及其背后的原理。
一、lambda 表达式的基本语法
[capture](parameter_list) -> return_type {
function_body
};
- capture:捕获外部变量的方式([] 中)
- parameter_list:参数列表,类似普通函数
- return_type(可省略):返回值类型(如果能推导出来)
- function_body:函数体
例子:
auto add = [](int a, int b) -> int {
return a + b;
};
std::cout << add(3, 5); // 输出:8
如果返回值可以自动推导,-> int 可省略:
auto add = [](int a, int b) { return a + b; };
二、捕获变量(capture list)
lambda 能访问作用域中的外部变量,通过捕获列表定义捕获方式:
捕获方式:
| 捕获形式 | 说明 |
|---|---|
[] |
不捕获任何变量 |
[=] |
以值捕获所有外部变量 |
[&] |
以引用捕获所有外部变量 |
[x] |
以值捕获变量 x |
[&x] |
以引用捕获变量 x |
[=, &x] |
默认值捕获,但 x 用引用 |
[&, x] |
默认引用捕获,但 x 用值 |
示例:
int x = 10, y = 20;
auto f1 = [=]() { return x + y; }; // 值捕获
auto f2 = [&]() { x += 1; y += 1; }; // 引用捕获
auto f3 = [x, &y]() { return x + (++y); }; // 混合捕获
注意:默认情况下,lambda 是不可修改捕获变量值的,除非加上 mutable 关键字。
int a = 5;
auto f = [a]() mutable {
a += 10; // OK
std::cout << a << std::endl;
};
f(); // 输出:15
std::cout << a << std::endl; // 输出:5
三、lambda 与 STL 算法搭配使用
lambda 在 STL 算法中用得最多,比如 std::sort、std::for_each 等:
std::vector<int> v = {3, 1, 4, 2};
std::sort(v.begin(), v.end(), [](int a, int b) {
return a > b;
});
std::for_each(v.begin(), v.end(), [](int x) {
std::cout << x << " ";
});
四、lambda 的返回类型推导
如果 return 语句只有一个,C++ 能自动推导返回类型:
auto square = [](int x) { return x * x; };
如果有多个 return 且类型不同,必须指定返回类型:
auto f = [](bool b) -> double {
if (b) return 3.14;
else return 2;
};
五、lambda 是什么?它是函数对象!
lambda 表达式本质上是一个编译器生成的匿名类,实现了 operator():
auto lambda = [](int x) { return x + 1; };
lambda(5); // 实际上调用的是 lambda.operator()(5)
你可以通过 typeid(lambda).name() 查看它的类型(是编译器生成的闭包类)。
六、lambda 的高级用法
捕获 this 指针
在类中使用 lambda 时经常捕获 this:
class Counter {
public:
int count = 0;
void start() {
auto inc = [this]() { ++count; };
inc();
}
};
与 std::function 搭配
std::function<int(int, int)> func = [](int a, int b) {
return a + b;
};
返回 lambda(C++14 后)
auto make_adder(int n) {
return [n](int x) { return x + n; };
}
auto add5 = make_adder(5);
std::cout << add5(10); // 输出:15
七、总结
| 特性 | 描述 |
|---|---|
| 匿名性 | 可定义无需命名的函数 |
| 捕获变量 | 可访问外部作用域变量 |
| 灵活性 | 可传入 STL 算法、自定义函数 |
| 高效 | 编译器优化,性能堪比函数指针甚至内联 |
| 可读性 | 代码更简洁清晰 |
结语
lambda 是现代 C++ 最重要的特性之一,极大提高了代码的表达力。在多线程编程、回调函数、STL 算法中,lambda 的作用不可替代。建议在实际编程中多加练习,熟练掌握各种捕获形式与使用场景。
下一篇,我们将介绍 C++ 中的 std::function 与 std::bind,进一步扩展函数对象的灵活使用,敬请期待!
如果你有任何问题,欢迎评论交流~

浙公网安备 33010602011771号