I wanted to write a lambda that returns itself, so I could call it multiple times on the spot. But it looks like inside of a lambda this
refers not to the lambda but to the surrounding object's this
, if the lambda is defines inside a member function.
Here's an example:
#include <iostream>
int main(int argc, char* argv[]) {
int a = 5;
[&](int b) {
std::cout << (a + b) << std::endl;
return *this;
}(4)(6);
}
Is there a way to do something comparable?
With old functor:
int main() {
int a = 5;
struct S {
const S& operator ()(int b) const {
std::cout << (a + b) << std::endl;
return *this;
}
const int& a;
};
S{a}(4)(6);
}
Demo
You cant return the lambda itself, but you can return a different one:
#include <iostream>
int main() {
int a = 5;
[&](int b) {
auto impl = [&](int b){std::cout << (a + b) << std::endl;};
impl(b);
return impl;
}(4)(6);
}
However, this allows only to call it one more time. Not sure if there is some trick to get more out of it...
Ben Voigt proposes to use Y combinators (which are a great proposal to the standard library, BTW), but your problem is simpler. You can introduce a small template functor that will be called instead of the lambda:
template<typename T>
struct recallable_impl {
template<typename... Args>
recallable_impl& operator()(Args&&... args) {
f(std::forward<Args>(args)...);
return *this;
}
template<typename F>
recallable_impl(F&& f)
: f{std::forward<F>(f)}
{}
private:
T f;
};
template<typename T>
decltype(auto) recallable(T&& f) {
return recallable_impl<std::decay_t<T>>(std::forward<T>(f));
}
Your lambda will then not even need to explicitly return anything:
int main() {
int a = 5;
recallable([&](int b){std::cout << (a + b) << std::endl;})(4)(5)(6)(7)(8);
}
You can call a lambda if you assign it to a predifned type (not auto), and it gets captured:
std::function<void(int)> f =[&f](int n)
{
if (n>0) f(n-1);
return;
};