C++ Lambda 表达式详解

C++ Lambda 表达式详解

Lambda 表达式是 C++11 引入的一项重要特性,它允许在代码中内联定义匿名函数对象。Lambda 极大地简化了代码编写,特别是在使用 STL 算法时。

基本语法

Lambda 表达式的基本语法如下:

复制代码
[捕获列表](参数列表) -> 返回类型 { 函数体 }

其中:

  • 捕获列表:定义 lambda 表达式可以访问的外部变量

  • 参数列表:与普通函数的参数列表类似

  • 返回类型:可以省略,编译器会自动推导

  • 函数体:包含 lambda 表达式的执行代码

捕获列表详解

捕获列表决定了 lambda 表达式如何访问外部变量:

  1. 值捕获 [=][var]

    复制代码
    int x = 10;
    auto lambda = [x] { return x; };  // 捕获x的值
  2. 引用捕获 [&][&var]

    复制代码
    int y = 20;
    auto lambda = [&y] { y++; };  // 捕获y的引用
  3. 混合捕获

    复制代码
    int a = 1, b = 2;
    auto lambda = [a, &b] { return a + b; };  // a值捕获,b引用捕获
  4. 隐式捕获

    复制代码
    [=]  // 所有变量值捕获
    [&]  // 所有变量引用捕获
    [=, &var]  // 除var外值捕获,var引用捕获
    [&, var]  // 除var外引用捕获,var值捕获

参数列表

与普通函数类似,但有以下特点:

  • 可以省略参数列表(如果没有参数)

  • 支持 auto 参数(C++14 起)

  • 支持可变参数模板

复制代码
auto lambda1 = [] { return 42; };  // 无参数
auto lambda2 = [](int a, int b) { return a + b; };  // 带参数
auto lambda3 = [](auto x, auto y) { return x * y; };  // C++14 auto参数

返回类型

返回类型可以显式指定,也可以由编译器自动推导:

复制代码
auto lambda1 = [] { return 42; };  // 返回类型推导为int
auto lambda2 = []() -> double { return 3.14; };  // 显式指定返回类型

当函数体中有多个 return 语句且返回类型不一致时,必须显式指定返回类型。

mutable 关键字

默认情况下,值捕获的变量在 lambda 内是 const 的。使用 mutable 可以修改这些副本:

复制代码
int x = 10;
auto lambda = [x]() mutable { x++; return x; };
// x的副本被修改,但外部的x不变

示例代码

复制代码
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    // 简单lambda示例
    auto greet = [] { std::cout << "Hello, Lambda!\n"; };
    greet();
    
    // 带参数的lambda
    auto add = [](int a, int b) { return a + b; };
    std::cout << "5 + 3 = " << add(5, 3) << "\n";
    
    // 在STL算法中使用lambda
    std::vector<int> nums = {1, 2, 3, 4, 5};
    std::for_each(nums.begin(), nums.end(), [](int n) {
        std::cout << n << " ";
    });
    std::cout << "\n";
    
    // 捕获局部变量
    int factor = 2;
    auto multiply = [factor](int n) { return n * factor; };
    std::transform(nums.begin(), nums.end(), nums.begin(), multiply);
    
    // 引用捕获修改外部变量
    int sum = 0;
    std::for_each(nums.begin(), nums.end(), [&sum](int n) { sum += n; });
    std::cout << "Sum: " << sum << "\n";
    
    // mutable示例
    int counter = 0;
    auto increment = [counter]() mutable { return ++counter; };
    increment();
    increment();
    std::cout << "Counter inside lambda: " << increment() << "\n";
    std::cout << "Counter outside: " << counter << "\n";
    
    return 0;
}

高级用法

  1. 泛型 lambda (C++14):

    复制代码
    auto generic_lambda = [](auto x, auto y) { return x + y; };
  2. 模板 lambda (C++20):

    复制代码
    auto template_lambda = []<typename T>(T x, T y) { return x * y; };
  3. 立即调用 lambda:

    复制代码
    const int result = [](int x) { return x * x; }(5);  // 结果是25
  4. 作为函数参数传递:

    复制代码
    void process(const std::function<void(int)>& f) {
        f(42);
    }
    
    process([](int x) { std::cout << x << "\n"; });

Lambda 表达式是现代 C++ 编程中非常强大的工具,合理使用可以大大简化代码并提高可读性。

相关推荐
草莓熊Lotso5 小时前
Linux 基础 IO 初步解析:从 C 库函数到系统调用,理解文件操作本质
linux·运维·服务器·c语言·数据库·c++·人工智能
梵刹古音5 小时前
【C语言】 字符数组相关库函数
c语言·开发语言·算法
闻缺陷则喜何志丹5 小时前
P8699 [蓝桥杯 2019 国 B] 排列数|普及+
c++·数学·蓝桥杯·数论·洛谷·数列
D_evil__11 小时前
【Effective Modern C++】第三章 转向现代C++:16. 让const成员函数线程安全
c++
微风中的麦穗11 小时前
【MATLAB】MATLAB R2025a 详细下载安装图文指南:下一代科学计算与工程仿真平台
开发语言·matlab·开发工具·工程仿真·matlab r2025a·matlab r2025·科学计算与工程仿真
2601_9491465311 小时前
C语言语音通知API示例代码:基于标准C的语音接口开发与底层调用实践
c语言·开发语言
开源技术12 小时前
Python Pillow 优化,打开和保存速度最快提高14倍
开发语言·python·pillow
学嵌入式的小杨同学12 小时前
从零打造 Linux 终端 MP3 播放器!用 C 语言实现音乐自由
linux·c语言·开发语言·前端·vscode·ci/cd·vim
wfeqhfxz258878212 小时前
YOLO13-C3k2-GhostDynamicConv烟雾检测算法实现与优化
人工智能·算法·计算机视觉
Aaron158813 小时前
基于RFSOC的数字射频存储技术应用分析
c语言·人工智能·驱动开发·算法·fpga开发·硬件工程·信号处理