📜  C++ 中的递归 lambda 表达式(1)

📅  最后修改于: 2023-12-03 15:13:58.997000             🧑  作者: Mango

C++ 中的递归 lambda 表达式

在 C++11 中,引入了 lambda 表达式,可以用来简化代码并增强可读性。除了普通的 lambda 表达式以外,C++11 还支持递归 lambda 表达式,可以在 lambda 表达式内部递归调用自身。

语法

递归 lambda 表达式的语法与普通的 lambda 表达式类似,只不过在函数参数列表后面需要添加一个额外的括号对,用于声明 lambda 表达式本身。例如:

[](int x, auto f) -> int {
  if (x == 0) {
    return 1;
  } else {
    return x * f(x - 1, f);
  }
} (5, [](int x, auto f) -> int {
  if (x == 0) {
    return 1;
  } else {
    return x * f(x - 1, f);
  }
});
说明

在递归 lambda 表达式内部,由于 lambda 表达式本身就是一个函数对象,因此可以通过捕获的方式,将 lambda 表达式本身传递给自身的函数参数列表,实现递归调用。

需要注意的是,如果在 lambda 表达式内部捕获了 this 指针,那么不可以直接将 lambda 表达式传递给自身的函数参数列表,因为 lambda 表达式的类型中会包含 this 指针,造成递归调用时的类型错误。此时可以使用 std::function 来封装 lambda 表达式,解决类型问题。例如:

struct Foo {
  void bar() {
    int result = [](int x, std::function<int(int, std::function<int(int)>)> f) -> int {
      if (x == 0) {
        return 1;
      } else {
        return x * f(x - 1, f);
      }
    } (5, [](int x, std::function<int(int)> f) -> int {
      if (x == 0) {
        return 1;
      } else {
        return x * f(x - 1);
      }
    });
    std::cout << result << std::endl;
  }
};
总结

递归 lambda 表达式可以增强代码的灵活性、简洁性和可读性,但是需要注意类型推导和语法格式,特别是当捕获了 this 指针时。因此,在使用递归 lambda 表达式时需要谨慎处理。