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::sortstd::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,进一步扩展函数对象的灵活使用,敬请期待!


如果你有任何问题,欢迎评论交流~

posted @ 2025-07-21 22:22  seekwhale13  阅读(171)  评论(0)    收藏  举报