C++11 示例:
在 C++11 中,实现纯 lambda 递归通常需要借助 std::function 来定义一个可以接受自身作为参数的 lambda。这实际上又回到了使用 std::function 的情况,但如果我们严格理解为“初始定义时不直接使用 std::function”,可以采用以下模式:
#include
#include
int main() {
auto factorial_gen = [](auto self) -> std::function {
return [&](int n) {
if (n <= 1) {
return 1;
}
return n * self(self)(n - 1);
};
};
auto factorial = factorial_gen(factorial_gen);
int num = 5;
std::cout << "C++11: " << num << " 的阶乘是: " << factorial(num) << std::endl;
return 0;
}
解释:
- 我们定义了一个名为 factorial_gen 的 lambda,它接受一个参数 self(代表它自身)。
- factorial_gen 返回另一个 lambda,这个返回的 lambda 才是实际计算阶乘的函数。
- 在返回的 lambda 内部,我们通过 self(self) 来获取自身(即阶乘函数),然后进行递归调用。
- 最后,我们通过 factorial_gen(factorial_gen) 来“绑定”这个递归关系,得到最终的 factorial 函数。
C++14 示例:
C++14 的泛型 lambda 可以使代码更简洁一些,但核心思想不变。
#include
#include
int main() {
auto factorial_gen = [](auto self) {
return [&](auto n) {
if (n <= 1) {
return 1;
}
return n * self(self)(n - 1);
};
};
auto factorial = factorial_gen(factorial_gen);
int num = 5;
std::cout << "C++14: " << num << " 的阶乘是: " << factorial(num) << std::endl;
return 0;
}
解释:
- 泛型 lambda 允许我们使用 auto 作为参数类型,减少了显式类型转换的需求。
C++17 示例:
C++17 在这方面没有引入显著的新特性来简化纯 lambda 递归。代码结构与 C++14 类似。
#include
#include
int main() {
auto factorial_gen = [](auto self) {
return [&](auto n) {
if (n <= 1) {
return 1;
}
return n * self(self)(n - 1);
};
};
auto factorial = factorial_gen(factorial_gen);
int num = 5;
std::cout << "C++17: " << num << " 的阶乘是: " << factorial(num) << std::endl;
return 0;
}
C++20 示例:
C++20 引入了模板 lambda,虽然在这个简单的例子中可能看不出明显的优势,但在更复杂的场景下,模板 lambda 可以提供更强的灵活性。核心的自传递模式仍然适用。
#include
#include
int main() {
auto factorial_gen = [](auto self) {
return [&](auto n) {
if (n <= 1) {
return 1;
}
return n * self(self)(n - 1);
};
};
auto factorial = factorial_gen(factorial_gen);
int num = 5;
std::cout << "C++20: " << num << " 的阶乘是: " << factorial(num) << std::endl;
return 0;
}
总结:
在不直接使用 std::function 进行初始定义的情况下,使用纯 lambda 实现递归通常需要采用一种“自传递”的模式。这种模式通过创建一个生成递归函数的 lambda,该 lambda 接受自身作为参数,从而实现递归调用。虽然这种方式在语法上比较巧妙,但在实际开发中,为了代码的可读性和维护性,更常见和推荐的做法是使用 std::function 来明确定义递归 lambda 的类型。
希望这些示例能够帮助您理解在不同版本的 C++ 中使用纯 lambda 实现递归的方法。