# i、lambda 表达式 vs 函数

在 C++ 中,定义 lambda 表达式和定义普通函数有以下几个区别和好处:

  1. 简洁性:相对于显式定义一个命名函数,lambda 表达式更加简洁。您可以在需要的地方直接定义 lambda 表达式,而无需显式命名函数。
  2. 匿名性:lambda 表达式是匿名的,它不需要命名,并且可以直接作为参数传递给其他函数或算法。
  3. 上下文捕获:lambda 表达式可以捕获外部作用域中的变量,包括局部变量、函数参数等。这使得它们能够在函数对象中保持状态,并在需要时访问和修改这些变量。
  4. 类型推导:lambda 表达式可以通过类型推导来自动推断其参数类型和返回类型。这使得编写 lambda 表达式更加方便,无需显式指定类型。
  5. 内联函数:编译器通常会将 lambda 表达式视为内联函数,这意味着它们的代码将在使用它们的地方直接插入,而不会引入额外的函数调用开销。
  6. 便于函数对象的创建:lambda 表达式本质上是一种函数对象的创建方式。它们可以被存储在变量中,作为函数参数传递,或者作为函数的返回值返回。

总体而言,lambda 表达式提供了一种更为简洁和灵活的定义函数对象的方式。它们在需要临时性的、简单的函数行为时非常有用,避免了显式定义命名函数的繁琐过程,并且通过上下文捕获和内联函数的特性,使得代码更加紧凑和可读。此外,lambda 表达式与 STL(标准模板库)算法的结合使用可以极大地简化代码,并提高代码的可读性和可维护性。

以上是 gpt 提供的答案,个人而言,我觉得最大的好处似乎也就是匿名性和间接性,使得我可以随时在任何地方生成一个函数对象进行调用。

# i、lambda 表达式对变量的捕获

捕获(Capture)是指在 lambda 表达式中访问并绑定外部作用域中的变量。Lambda 表达式可以捕获局部变量、函数参数、全局变量或静态成员变量等。通过捕获,lambda 表达式可以在其函数体中引用这些变量,并且可以在函数对象的生命周期内保持对这些变量的状态。

在 C++ 中,有两种主要的捕获方式:

  1. 值捕获(Value Capture):通过值捕获,lambda 表达式可以在创建时复制并绑定外部变量的值。这意味着 lambda 函数体中使用的变量将保留捕获时的值,即使外部作用域的变量发生改变也不会影响 lambda 表达式内部的值。
    例如:
    1
    2
    3
    4
    5
    int x = 5;
    auto lambda = [x]() {
    // 使用值捕获的变量x
    // ...
    };
  2. 引用捕获(Reference Capture):通过引用捕获,lambda 表达式可以在创建时绑定外部变量的引用。这意味着 lambda 函数体中使用的变量将与外部作用域中的变量共享相同的存储位置,对变量的修改会影响到外部作用域的值。
    例如:
    1
    2
    3
    4
    5
    int y = 10;
    auto lambda = [&y]() {
    // 使用引用捕获的变量y
    // ...
    };

在 lambda 表达式中,可以同时使用值捕获和引用捕获,并对不同的变量使用不同的捕获方式。此外,还可以使用捕获列表(Capture List)来指定需要捕获的变量以及捕获方式。

捕获使得 lambda 表达式可以在函数对象内部访问和操作外部作用域中的变量。通过捕获,lambda 函数对象可以维持对这些变量的状态,并在其生命周期内使用和修改它们。这使得 lambda 表达式在需要访问外部状态的回调函数、算法和并行编程等场景中非常有用。

更新于

请我喝杯咖啡吧~

Rick 微信支付

微信支付

Rick 支付宝

支付宝