C++ 中的可变 lambda

2025 年 5 月 21 日 | 阅读 4 分钟

C++ 中的 Lambda 函数 提供了一种简洁的方式来定义小型私有函数。默认情况下,Lambda 函数可以通过值或引用捕获其周围作用域中的变量。但是,如果没有 mutable 关键字,捕获的变量不能被更改。使用 mutable 关键字的 Lambda 函数可以更改那些按值捕获的变量。C++ 中的 可变 Lambda 表达式有几个方面。

  1. 变量捕获:在 Lambda 函数中,变量按值捕获,这会导致为 Lambda 创建变量的副本。此副本默认按 const 处理,不能在 Lambda 内部更改,这会阻止 Lambda 更改封闭作用域中的变量。
  2. mutable 的引入:Lambda 最初是在 C++11 中引入的,但它们不具备更改捕获变量的能力。但是,由于 C++14 中添加了 mutable 关键字,Lambda 现在在更改 Lambda 主体内的变量方面拥有了额外的自由。它允许 Lambda 更改按值捕获的变量。
  3. mutable 的使用:当 Lambda 在其参数列表之前放置 mutable 关键字时,它可以更改按值捕获的变量。这在 Lambda 必须更改变量或保留内部状态而不影响其作用域之外的变量的情况下特别有用。
  4. 更改范围:对 Lambda 内部按值记录的变量所做的更改只会影响 Lambda 内部的变量;它们不会影响其外部的原始变量。
  5. 没有 mutable 的不变性:如果未使用 mutable 关键字,则按值捕获的变量在 Lambda 内部保持 const,从而确保 Lambda 不会更改这些变量。
  6. 局部修改:在可变 Lambda 中,对捕获的变量所做的更改限制在 Lambda 的作用域内。这被称为局部修改。这些更改的结果是,初始作用域变量保持不变。
  7. 用例
    • 当我们需要在 Lambda 内部更改局部变量而不更改 Lambda 作用域之外的原始变量时,可变 Lambda 会派上用场。
    • 它们经常用于算法、for_each 循环以及我们希望对集合中的元素执行副作用操作同时保持原始集合的其他上下文中。

示例

让我们举一个例子来说明 C++ 中的 可变 Lambda 表达式。

输出

Before calling the lambda: 5
Inside mutable lambda: 15
After calling the lambda: 5  

说明

  1. 此行 `#include ` 包含了输入输出流操作所需的库。
  2. int main():它是启动程序执行的主函数。
  3. int value = 5;:此行将整数变量的初始值设置为 5。
  4. auto mutableLambda = mutable {... };:此行声明了一个名为 `mutableLambda` 的可变 Lambda 函数;它按值检索变量的值。由于可变关键字,捕获的变量可以由 Lambda 更改。
  5. value += 10;:在 Lambda 内部,将 10 添加到捕获的变量 `value`。
  6. `std::cout << "Inside mutable lambda: " << value << std::endl;`:此行输出 Lambda 内部已更新的值。
  7. `std::cout << "Before calling the lambda: " << value << std::endl;`:在调用 Lambda 之前,此行打印启动时的值。
  8. mutableLambda();:此行调用在 Lambda `mutableLambda` 的作用域内更新捕获变量值的函数。
  9. `std::cout << "After calling the lambda: " << value << std::endl;`:Lambda 调用后,此行打印 `value` 的值。在 Lambda 作用域之外,原始变量 `value` 保持不变,因为 Lambda 逐个捕获值。
  10. return 0;:此行标志着主函数和程序成功运行的结束。

结论

总而言之,该代码展示了如何利用 可变 Lambda 表达式在本地作用域内更改捕获的变量。在 Lambda 内部对捕获变量进行的更改不会影响 Lambda 作用域之外的原始变量。为了使捕获的 变量 能够被修改,`mutable` 关键字至关重要。