如何在C++中使用lambda表达式

来源:个人站长网作者:弦宿​头衔:草根站长
导读:本期聚焦于小伙伴创作的《如何在C++中使用lambda表达式》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何在C++中使用lambda表达式》有用,将其分享出去将是对创作者最好的鼓励。

C++中的lambda表达式是一种可以定义在语句或表达式内部的匿名函数对象,它不需要单独的函数名,能够直接 inline 到代码中,非常适合编写短小的回调函数或者临时逻辑。

如何在C++中使用lambda表达式

lambda表达式的基本语法

C++ lambda表达式的完整语法结构如下:

[capture_list](parameter_list) mutable noexcept -> return_type {
    // 函数体
}

其中各个部分的含义如下:

  • capture_list(捕获列表):用来捕获外部作用域的变量,是lambda表达式和普通函数最大的区别之一,这部分可以为空。
  • parameter_list(参数列表):和普通函数的参数列表一致,如果没有参数可以省略括号。
  • mutable:可选关键字,默认情况下lambda捕获的变量是只读的,加上mutable可以让捕获的变量在lambda内部被修改。
  • noexcept:可选关键字,标记lambda不会抛出异常。
  • return_type(返回类型):可以省略,编译器会自动推导返回类型,如果需要显式指定则加上->返回类型。
  • 函数体:和普通函数的函数体一致,写具体的执行逻辑。

捕获列表的常见用法

捕获列表决定了lambda可以访问哪些外部变量,以及是按值还是按引用访问,常见的捕获方式有:

捕获方式含义
[]不捕获任何外部变量
[x]按值捕获变量x,lambda内部x是只读的副本
[&x]按引用捕获变量x,lambda内部修改x会影响外部的x
[=]按值捕获所有外部自动变量
[&]按引用捕获所有外部自动变量
[=, &x]除了x按引用捕获,其他所有变量按值捕获
[&, x]除了x按值捕获,其他所有变量按引用捕获

下面是一个捕获列表的使用示例:

#include <iostream>

int main() {
    int a = 10;
    int b = 20;
    
    // 按值捕获a,按引用捕获b
    auto lambda1 = [a, &b]() {
        // a++;  // 错误,按值捕获的变量默认只读
        b++;    // 正确,按引用捕获可以修改
        std::cout << "lambda内部 a:" << a << " b:" << b << std::endl;
    };
    
    lambda1();
    std::cout << "外部 a:" << a << " b:" << b << std::endl;
    
    // 加上mutable后可以修改按值捕获的变量
    auto lambda2 = [a]() mutable {
        a++;
        std::cout << "mutable lambda内部 a:" << a << std::endl;
    };
    lambda2();
    std::cout << "外部 a 依然不变:" << a << std::endl;
    
    return 0;
}

lambda表达式的常见实践场景

配合STL算法使用

lambda最常见的用途是作为STL算法的回调函数,比如std::sortstd::for_each等,避免单独定义函数对象,让代码更紧凑。

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6};
    
    // 使用lambda作为排序的比较规则,按降序排序
    std::sort(nums.begin(), nums.end(), [](int x, int y) {
        return x > y;
    });
    
    // 使用lambda遍历输出元素
    std::for_each(nums.begin(), nums.end(), [](int num) {
        std::cout << num << " ";
    });
    std::cout << std::endl;
    
    return 0;
}

作为回调函数使用

在事件处理、异步操作等场景中,lambda可以直接作为回调函数传入,不需要额外定义函数。

#include <iostream>
#include <functional>

// 模拟一个异步操作,完成后执行回调
void async_task(std::function<void(int)> callback) {
    // 模拟任务执行
    int result = 100;
    // 执行回调
    callback(result);
}

int main() {
    // 直接传入lambda作为回调
    async_task([](int res) {
        std::cout << "异步任务结果:" << res << std::endl;
    });
    
    return 0;
}

lambda和普通函数、函数对象的区别

  • 和普通函数相比,lambda可以捕获外部变量,更灵活,适合编写短小的临时逻辑,不需要额外的函数定义。
  • 和函数对象(重载了operator()的类)相比,lambda的语法更简洁,编译器会自动生成对应的函数对象类,不需要手动定义类。
  • lambda的类型是编译器自动生成的匿名类型,无法直接写出类型名,通常配合auto或者std::function使用。

注意事项

  • 按引用捕获的时候要注意变量的生命周期,避免lambda执行时引用的变量已经被销毁,导致悬垂引用。
  • 如果lambda不需要捕获任何变量,尽量使用[]空捕获列表,避免不必要的捕获。
  • lambda的返回类型可以省略,编译器会自动推导,但是如果函数体有多个return语句返回不同类型,就需要显式指定返回类型。

C++lambda表达式函数对象STL算法闭包修改时间:2026-06-26 17:21:37

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。