C++:Lambda表达式

C++:Lambda表达式

      • C++中`lambda`的基本语法
      • [1. 捕获列表(Capture List)](#1. 捕获列表(Capture List))
      • [2. 示例代码](#2. 示例代码)
        • [示例 1:简单的`lambda`](#示例 1:简单的lambda)
        • [示例 2:捕获变量](#示例 2:捕获变量)
        • [示例 3:按引用捕获](#示例 3:按引用捕获)
        • [示例 4:捕获所有变量](#示例 4:捕获所有变量)
        • [示例 5:作为函数参数](#示例 5:作为函数参数)
      • [3. `lambda`的高级特性](#3. lambda的高级特性)
      • [4. 适用场景](#4. 适用场景)
      • [5. 注意事项](#5. 注意事项)
      • 总结

在C++中,lambda表达式是一种强大的特性,用于创建匿名函数对象。它从C++11标准开始引入,并在后续版本中不断完善。lambda表达式在C++中广泛应用于标准库算法(如std::sortstd::for_each等)以及其他需要函数对象的场景。

代码链接:https://gitee.com/hu_yuchen/C++11/lambda

C++中lambda的基本语法

C++的lambda表达式语法如下:

cpp 复制代码
[capture](parameters) -> return_type { body }
  • capture:捕获列表,用于捕获当前作用域中的变量。
  • parameters:参数列表,类似于普通函数的参数。
  • -> return_type:返回类型(可选)。如果不指定,编译器会自动推导返回类型。
  • body:函数体,包含具体的逻辑。

1. 捕获列表(Capture List)

捕获列表用于将当前作用域中的变量捕获到lambda表达式中。捕获方式有以下几种:

  • 按值捕获:使用[x]捕获变量x的副本。
  • 按引用捕获:使用[&x]捕获变量x的引用。
  • 捕获所有变量:使用[=]按值捕获当前作用域中所有变量。
  • 捕获所有变量的引用:使用[&]按引用捕获当前作用域中所有变量。
  • 混合捕获:可以同时使用按值和按引用捕获,例如[x, &y]

2. 示例代码

以下是一些C++中lambda表达式的典型用法:

示例 1:简单的lambda
cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>

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

    // 使用 lambda 表达式作为回调函数
    std::for_each(vec.begin(), vec.end(), [](int x) {
        std::cout << x << " ";
    });
    std::cout << std::endl;

    return 0;
}

输出:

复制代码
1 2 3 4 5
示例 2:捕获变量
cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    int factor = 2;
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 按值捕获变量 factor
    std::for_each(vec.begin(), vec.end(), [factor](int x) {
        std::cout << x * factor << " ";
    });
    std::cout << std::endl;

    return 0;
}

输出:

复制代码
2 4 6 8 10
示例 3:按引用捕获
cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    int factor = 2;
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 按引用捕获变量 factor
    std::for_each(vec.begin(), vec.end(), [&factor](int x) {
        std::cout << x * factor << " ";
        factor++;  // 修改捕获的变量
    });
    std::cout << std::endl;

    std::cout << "Final value of factor: " << factor << std::endl;

    return 0;
}

输出:

复制代码
2 6 12 20 30
Final value of factor: 7
示例 4:捕获所有变量
cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    int a = 2;
    int b = 3;

    // 捕获所有变量
    auto lambda = [=](){ return a * b; };

    std::cout << "Result: " << lambda() << std::endl;

    return 0;
}

输出:

复制代码
Result: 6
示例 5:作为函数参数
cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>

void processVector(const std::vector<int>& vec, void (*func)(int)) {
    for (int x : vec) {
        func(x);
    }
}

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

    // 使用 lambda 表达式作为函数参数
    processVector(vec, [](int x) {
        std::cout << x * x << " ";
    });
    std::cout << std::endl;

    return 0;
}

输出:

复制代码
1 4 9 16 25

3. lambda的高级特性

  • 可调用对象:lambda表达式本质上是一个可调用对象,可以赋值给std::function或其他支持函数调用的类型。

  • 默认捕获模式:可以指定默认捕获模式,例如[=, &x]表示按值捕获所有变量,但x按引用捕获。

  • mutable关键字:如果lambda需要修改捕获的变量,可以在lambda表达式中使用mutable关键字。

    cpp 复制代码
    auto lambda = [x = 5]() mutable { x++; std::cout << x << std::endl; };
    lambda();  // 输出 6

4. 适用场景

  • 标准库算法:如std::sortstd::for_eachstd::transform等,lambda表达式可以作为回调函数传递。
  • 线程创建:在std::thread中,可以使用lambda表达式作为线程函数。
  • 事件处理:在GUI编程或事件驱动的场景中,lambda表达式可以作为事件处理器。
  • 简化代码:对于简单的函数逻辑,lambda可以减少代码量,使代码更简洁。

5. 注意事项

  • 捕获变量的生命周期:如果捕获了局部变量的引用,需要确保lambda表达式在变量生命周期内使用,否则可能导致未定义行为。
  • 性能开销:虽然lambda表达式通常不会引入额外的性能开销,但捕获大量变量可能会增加内存使用。
  • 复杂逻辑:对于复杂的逻辑,建议使用普通函数而不是lambda表达式,以提高代码的可读性。

总结

C++中的lambda表达式是一种非常灵活和强大的特性,适用于需要简单函数对象的场景。通过合理使用捕获列表和参数列表,可以实现简洁高效的代码。

相关推荐
R-G-B18 小时前
【25】MFC入门到精通——MFC静态文本框 中字符串 连续输出 不覆盖先前的文本 换行输出
c++·mfc·mfc静态文本框输出字符串·mfc静态文本框连续输出字符串·mfc静态文本框换行输出字符串
我搞slam18 小时前
快乐数--leetcode
算法·leetcode·哈希算法
WWZZ202518 小时前
快速上手大模型:机器学习3(多元线性回归及梯度、向量化、正规方程)
人工智能·算法·机器学习·机器人·slam·具身感知
应用市场19 小时前
构建自定义命令行工具 - 打造专属指令体
开发语言·windows·python
东方佑19 小时前
从字符串中提取重复子串的Python算法解析
windows·python·算法
西阳未落20 小时前
LeetCode——二分(进阶)
算法·leetcode·职场和发展
通信小呆呆20 小时前
以矩阵视角统一理解:外积、Kronecker 积与 Khatri–Rao 积(含MATLAB可视化)
线性代数·算法·matlab·矩阵·信号处理
FFZero120 小时前
【C++/Lua联合开发】 (二) Lua调用C++函数
c++·junit·lua
Dfreedom.20 小时前
一文掌握Python四大核心数据结构:变量、结构体、类与枚举
开发语言·数据结构·python·变量·数据类型
一半烟火以谋生20 小时前
Python + Pytest + Allure 自动化测试报告教程
开发语言·python·pytest