How to get the address of a C++ lambda function within the lambda itself?

There is no way to directly get the address of a lambda object within a lambda prior to c++23.

Now, as it happens this is quite often useful. The most common use is in order to recurse.

The y_combinator comes from languages where you could not talk about yourself until you where defined. It can be implemented pretty easily in c++:

template<class F>
struct y_combinator {
  F f;
  template<class...Args>
  decltype(auto) operator()(Args&&...args) const {
    return f( f, std::forward<Args>(args)... );
  }
  template<class...Args>
  decltype(auto) operator()(Args&&...args) {
    return f( f, std::forward<Args>(args)... );
  }
};
template<class F>
y_combinator(F)->y_combinator<F>;

now you can do this:

y_combinator{ [](auto& self)-> void {
  std::cout<<"Address of this lambda function is => "<< &self;
} }();

There are a few useful variations. One variation I find particularly useful is:

template<class F>
struct y_combinator {
  F f;
  template<class...Args>
  decltype(auto) operator()(Args&&...args) const {
    return f( *this, std::forward<Args>(args)... );
  }
  template<class...Args>
  decltype(auto) operator()(Args&&...args) {
    return f( *this, std::forward<Args>(args)... );
  }
};

where the self passed can be called without passing in self as the first argument.

The second matches the real y combinator (aka the fixed point combinator) I believe. Which you want depends on what you mean by ‘address of lambda’.

There is also this pithy one:

template<class R, class...Args>
auto Y = [] (auto f) {
  auto action = [=] (auto action) -> std::function<R(Args...)> {
    return [=] (Args&&... args)->R {
      return f( action(action), std::forward<Args>(args)... );
    };
  };
  return action(action);
};

which returns a std function.


In c++23 accessing this within a lambda gets easier:

auto fib = [](this auto& self, int n) {
  if (n < 2) return n;
  return self(n-1) + self(n-2);
};

you can tag the first argument as this, and it becomes itself. It even works with the overload set trick, where self is the most-deduced type.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)