C++ 斐波那契 lambda 中的条件运算符

Cno*_*oob 3 c++ lambda function

在检查如何实现递归 lambda 函数时,我偶然发现了这个解决方案

#include <iostream>
using namespace std;

int main() {
    auto fr = [] (int n, auto&& fr) {
        if (n < 2)
            return n;
        else
            return fr(n-1,fr) + fr(n-2,fr);
    };
    auto fib = [&fr] (int n) {return fr(n,fr);};
    
    int n = 10;
    cout << "fib(" << n << ") = " << fib(n) << endl;
}
Run Code Online (Sandbox Code Playgroud)

效果很好。然而,尝试一些微妙的改变,例如

auto fr = [] (int n, auto&& fr) {
        return n < 2 ? n : fr(n-1,fr) + fr(n-2,fr);
    };
Run Code Online (Sandbox Code Playgroud)

给出以下编译错误:

error: use of 'main()::<lambda(int, auto:1&&)> [with auto:1 = main()::<lambda(int, auto:1&&)>&]' before deduction of 'auto'
Run Code Online (Sandbox Code Playgroud)

我缺少什么?

另外,我想到了另一种使代码更紧凑的方法,因为有两个 lambda 似乎有点混乱。通过在声明后放置括号,可以在声明后立即执行 lambda,那么是否可以执行这样的操作?

auto fib = [] (int n) {
        auto fr = [] (int n, auto&& fr) {
            return n < 2 ? n : fr(n-1,fr) + fr(n-2,fr);
        }(n, fr);
    };
Run Code Online (Sandbox Code Playgroud)

这样,当调用函数 fib 时,会自动声明并调用函数 fr。然而,我对 lambda 很陌生,不知道语法是否接近有意义......

提前致谢!

Sam*_*hik 7

这是一个微妙的先有鸡还是先有蛋的问题。

[] (int n, auto&& fr) { ... }
Run Code Online (Sandbox Code Playgroud)

在使用这个闭包之前,必须推断出它的返回类型。

 return n;
Run Code Online (Sandbox Code Playgroud)

n是一个int。这意味着闭包的return类型可以推断为int. 该return语句用于推断闭包的返回类型。

return n < 2 ? n : fr(n-1,fr) + fr(n-2,fr);
Run Code Online (Sandbox Code Playgroud)

该三元表达式的类型只能通过弄清楚此处适用的整数提升规则(如果有)来确定。其中一个表达式是n, and int,另一个表达式的类型是...到底是什么?这是未知的。失败。

解决方案是显式定义闭包的返回类型:

    auto fr = [] (int n, auto&& fr) -> int {
            return n < 2 ? n : fr(n-1,fr) + fr(n-2,fr);
    };
Run Code Online (Sandbox Code Playgroud)