C++ Lambda 函数

Lambda 函数

Lambda 函数是一种小巧的、匿名的函数,您可以直接在代码中编写。当您需要一个快速的函数而又不想单独命名或声明它时,它非常有用。

可以把它想象成一个"即用型迷你函数"。

语法

[捕获] (参数) { 代码 };

不用担心:我们稍后会解释 [捕获] 的含义。现在,我们只使用一对空括号。

基本 Lambda 示例

这里,message 持有一个 lambda 函数,该函数向屏幕打印一条消息:

实例

int main() {
  auto message = []() {
    cout << "Hello World!\n";
  };

  message();
  return 0;
}

结果:

Hello World!

亲自试一试

带参数的 Lambda

您可以像普通函数一样向 lambda 传递值:

#include <iostream>
using namespace std;

int main() {
  auto add = [](int a, int b) {
    return a + b;
  };

  cout << add(3, 4);
  return 0;
}

结果:

7

亲自试一试

将 Lambda 传递给函数

您也可以将 lambda 函数作为参数传递给另一个函数。

当您想告诉一个函数要做什么,而不仅仅是使用什么数据时,这非常有用。

在下面的例子中,我们向另一个函数发送一个小型 lambda 函数,然后该函数将其运行两次:

#include <iostream>
#include <functional> // 需要 std::function
using namespace std;

// 一个将另一个函数作为参数的函数
void myFunction(function<void()> func) {
  func();
  func();
}

int main() {
  auto message = []() {
    cout << "Hello World!\n";
  };

  myFunction(message);
  return 0;
}

结果:

Hello World!
Hello World!

亲自试一试

请注意,要使此例工作,您必须包含 <functional> 库。

在循环中使用 Lambda

您可以在循环内部定义和使用 lambda 函数,这对于快速操作非常有用:

#include <iostream>
using namespace std;

int main() {
  for (int i = 1; i <= 3; i++) {
    auto show = [i]() {
      cout << "数字:" << i << "\n";
    };
    show();
  }
  return 0;
}

结果:

数字:1
数字:2
数字:3

亲自试一试

捕获子句 []

您可以使用 [ ] 括号让 lambda 访问其外部的变量。

这被称为捕获子句

在这个例子中,lambda 通过值(一个副本)捕获变量 x

int main() {
  int x = 10;
  auto show = [x]() {
    cout << x;
  };

  show();
  return 0;
}

结果:

10

亲自试一试

注意:lambda 使用的是 x副本。如果您在定义 lambda 后更改 x,不会影响 lambda 内部的值。

注意:您也可以使用 [&] 通过引用捕获。

通过引用捕获

如果您希望 lambda 使用变量的最新值(而不仅仅是一个副本),可以使用 [&] 通过引用捕获它。

这意味着 lambda 将作用于原始变量,而不是一个单独的副本:

int main() {
  int x = 10;

  auto show = [&x]() {
    cout << x;
  };

  x = 20;  // 在 lambda 创建后更改 x

  show();
  return 0;
}

结果:

20

亲自试一试

为什么?lambda 看到的是原始的 x 变量,所以当您更改 x 时,lambda 会使用更新后的值。

普通函数 vs Lambda 函数

普通函数和 lambda 函数都允许您对代码进行分组并稍后运行,但它们使用的场景略有不同。

使用普通函数, 当:

  • 您计划在多个地方重用该函数
  • 您想给函数一个清晰、有意义的名称
  • 逻辑较长或复杂

使用 lambda 函数, 当:

  • 您只需要该函数一次
  • 代码简短且简单
  • 您想将一个快速函数传递给另一个函数

这两个例子都做同样的事情。它们返回两个数的和:

普通函数

int add(int a, int b) {
  return a + b;
}

Lambda 函数

auto add = [](int a, int b) {
  return a + b;
};

注意:当您以后不需要重用该函数时,lambda 版本非常有用。它很快速,并且在代码块内部或作为其他函数的参数时效果很好。