Browsing some internet board I encountered this little challenge:
"Implement a recursive anonymous function in your favorite language"
Obviously this is easy using a std::function/function pointer.
What I'm really interested in is if this is possible without binding the lambda to an identifier?
Something like (ignoring the obvious infinite recursion):
[](){ this(); }();
Of course, in C++, to call any function you have to bind it to an identifier somewhere, simply owing to syntax constraints. But, if you will accept parameters as being sufficiently unnamed, then it is possible to create a version of the y-combinator in C++ which recurses nicely without being "named".
Now, this is really ugly because I don't know how to do a typedef for a recursive lambda. So it just uses a lot of cast abuse. But, it works, and prints FLY!!
until it segfaults due to stack overflow.
#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);
});
}
The two lambdas are unnamed in the sense that neither is explicitly assigned to name anywhere. The second lambda is the real workhorse, and it basically calls itself by using the first lambda to obtain a reference to itself in the form of the parameter.
Here's how you would use this to do some "useful" work:
#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;
}
Are you allowed to cheat?
void f(){
[]{ f(); }();
}
It's recursive - indirectly, atleast.
Otherwise, no, there is no way to refer to the lambda itself without assigning it a name.
No identifier for functions/methods, Close enough or not !?
struct A
{
void operator()()
{
[&]()
{
(*this)();
}();
}
};
To call
A{}(); // Thanks MooningDuck
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With