调用lambda而不将其绑定到标识符

use*_*963 7 c++ lambda c++11

浏览一些互联网板我遇到了这个小挑战:

"用您喜欢的语言实现递归匿名函数"

显然,使用std :: function/function指针很容易.

我真正感兴趣的是,如果没有将lambda绑定到标识符,这是否可行?

像(忽略明显的无限递归)的东西:

[](){ this(); }();
Run Code Online (Sandbox Code Playgroud)

nne*_*neo 5

当然,在C++中,要调用任何函数,你必须将它绑定到某个地方的标识符,这仅仅是由于语法限制.但是,如果您将接受参数作为充分未命名的参数,则可以在C++中创建一个y-combinator版本,该版本可以很好地递归,而不会被"命名".

现在,这真的很难看,因为我不知道如何为递归lambda做一个typedef.所以它只是使用了大量的滥用行为.但是,它可以工作,并打印,FLY!!直到由于堆栈溢出而导致段错误.

#include <iostream>

typedef void(*f0)();
typedef void(*f)(f0);

int main() {
    [](f x) {
        x((f0)x);
    } ([](f0 x) {
        std::cout<<"FLY!!\n";
        ((f)x)(x);
    });
}
Run Code Online (Sandbox Code Playgroud)

这两个lambdas是未命名的,因为它们都没有明确地指定给任何名字.第二个lambda是真正的主力,它基本上通过使用第一个lambda以参数的形式获得对自身的引用来调用自身.

以下是如何使用它来做一些"有用"的工作:

#include <iostream>

typedef int param_t;
typedef int ret_t;

typedef void(*f0)();
typedef ret_t(*f)(f0, param_t);

int main() {
    /* Compute factorial recursively */
    std::cout << [](f x, param_t y) {
        return x((f0)x, y);
    } ([](f0 x, param_t y) {
        if(y == 0)
            return 1;
        return y*((f)x)(x, y-1);
    }, 10) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)