C++ lambda 表达式详细介绍

lambda 是 C++11 核心特性,本质是匿名临时函数------ 没有函数名、专门用于写简短、一次性的逻辑(比如 STL 算法的比较规则、回调函数),不用单独定义全局 / 类成员函数,代码极简。

1.完整语法

这是 lambda 的完整写法,日常用可以省略很多部分:

cpp 复制代码
[捕获列表] (参数列表) mutable -> 返回值类型 { 函数体 };
部分 作用(通俗版) 必选 / 可选
[捕获列表] 核心 :决定能不能访问外部变量,怎么访问 ✅ 必选
(参数列表) 和普通函数一样,写入参(如 int a, int b ⭕ 可选
mutable 允许修改值捕获的外部变量(默认值捕获是只读) ⭕ 可选
-> 返回值类型 指定函数返回值(编译器会自动推导,90% 场景不用写) ⭕ 可选
{ 函数体 } 写具体逻辑代码 ✅ 必选

2.基础示例

示例 1:最简 lambda(无参、无返回、无捕获)

没有参数,没有返回值,不访问任何外部变量,直接执行逻辑。

cpp 复制代码
#include <iostream>
using namespace std;

int main() {
    // 最简lambda:[] 无捕获,() 无参,{} 函数体
    []() {
        cout << "Hello Lambda!" << endl;
    }; // 这只是定义,不会执行

    // 加 () 直接调用
    []() {
        cout << "Hello Lambda! 我执行了" << endl;
    }(); 

    return 0;
}

输出:

cpp 复制代码
Hello Lambda! 我执行了

示例 2:带参数 + 带返回值

和普通函数一样传参、返回值,编译器自动推导返回值,不用写 ->。

cpp 复制代码
int main() {
    // 功能:计算两个数的和
    auto add = [](int a, int b) {
        return a + b; // 自动推导返回值为int
    };

    // 调用lambda
    cout << "1+2=" << add(1,2) << endl; 
    return 0;
}

输出:1+2=3

3.核心:捕获列表 \[\]

lambda 默认不能直接用外部变量,必须通过 捕获列表 授权,这是 lambda 的灵魂。

4 种最常用捕获方式:

写法 含义 特点
[] 不捕获任何外部变量 纯独立函数
[=] 值捕获:拷贝所有外部变量(只读) 不修改原变量,安全
[&] 引用捕获:直接用所有外部变量(可改) 会修改原变量
[a, &b] 定制捕获:a 值拷贝,b 引用 精准控制,推荐

示例 3:值捕获 = / 变量

✅ 拷贝一份外部变量,原变量不会被修改(只读)

cpp 复制代码
int main() {
    int x = 10;
    // [x]:只捕获x;[=]:捕获所有外部变量
    auto func = [x]() {
        // x = 20; ❌ 报错:值捕获默认只读
        cout << "捕获的x:" << x << endl;
    };

    func();
    cout << "原x:" << x << endl; // 原变量不变
    return 0;
}

输出:

cpp 复制代码
捕获的x:10
原x:10

示例 4:引用捕获 \&

✅ 直接使用外部变量的地址,修改会影响原变量

cpp 复制代码
int main() {
    int x = 10;
    // [&]:引用捕获所有外部变量
    auto func = [&]() {
        x = 20; // ✅ 可修改
        cout << "修改后的x:" << x << endl;
    };

    func();
    cout << "原x:" << x << endl; // 原变量被修改
    return 0;
}

输出:

cpp 复制代码
修改后的x:20
原x:20

示例 5:mutable 关键字

作用:允许修改 值捕获 的变量(仅修改拷贝的副本,原变量不变)

cpp 复制代码
int main() {
    int x = 10;
    // 加mutable:值捕获的变量可修改
    auto func = [x]() mutable {
        x = 20; // ✅ 允许修改
        cout << "lambda内x:" << x << endl;
    };

    func();
    cout << "原x:" << x << endl; // 原变量依旧是10
    return 0;
}

输出:

cpp 复制代码
lambda内x:20
原x:10

4.实战场景(lambda 最常用的地方)

lambda 90% 用于 STL 算法(排序、查找、遍历),替代繁琐的全局函数 / 函数对象。

示例 6:结合 sort 自定义排序规则

对数组 /vector 降序排序(不用写单独的比较函数)

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    vector<int> v = {3,1,4,2,5};

    // lambda 作为sort的比较函数
    sort(v.begin(), v.end(), [](int a, int b) {
        return a > b; // 降序:前一个数 > 后一个数
    });

    // 遍历:范围for + lambda
    for (int num : v) cout << num << " ";
    return 0;
}

输出:5 4 3 2 1

示例 7:结合 find_if 查找元素

查找第一个大于 3 的数字:

cpp 复制代码
int main() {
    vector<int> v = {1,2,4,3,5};
    // find_if:遍历容器,返回第一个满足条件的迭代器
    auto it = find_if(v.begin(), v.end(), [](int x) {
        return x > 3; // 查找条件
    });

    if (it != v.end()) cout << "找到:" << *it << endl;
    return 0;
}

输出:找到:4

示例 8:类中使用 lambda(捕获 this)

在类的成员函数里,用 lambda 访问成员变量,必须捕获 this。

cpp 复制代码
#include <iostream>
using namespace std;

class Test {
private:
    int val = 100;
public:
    void show() {
        // [this]:捕获当前类对象,访问成员变量/函数
        [this]() {
            cout << "类成员变量:" << val << endl;
        }();
    }
};

int main() {
    Test t;
    t.show();
    return 0;
}

输出:类成员变量:100

5.核心总结

本质:匿名临时函数,专门写简短、一次性逻辑
核心:捕获列表
\[\]:不捕获
=:值捕获(只读,拷贝)
\&:引用捕获(可改原变量)
this:类中捕获成员变量
关键字:mutable → 允许修改值捕获的变量
最佳场景:STL 算法(sort、find_if、for_each)
简化:参数、返回值都可以省略,编译器自动推导

谢谢

相关推荐
BadBadBad__AK4 小时前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境16 小时前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境17 小时前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
郝学胜_神的一滴2 天前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
卷无止境4 天前
C++ 的Eigen 库全解析
c++
卷无止境4 天前
现代 C++特性大盘点:一门脱胎换骨的老语言
c++·后端
郝学胜_神的一滴4 天前
CMake 27:缓存变量的特性、语法、类型与实操全解
c++·cmake
博客18006 天前
酷宝的使用方法,超好用的免费界面库,C++、MFC可用
c++·mfc·界面库·库来帮·酷宝
郝学胜_神的一滴6 天前
CMake 026:属性体系精讲、四大作用域全解 & 实战代码落地
c++·cmake
众少成多积小致巨6 天前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++