I'm having a trouble finding a definitive answer if the following code is correct in both cases, with non-capturing lambda and with call of a static function. I'm pretty sure the latter is fine, what I'm concerned about is the lifetime of a lambda when "defined" inside another block/function call, etc. The code seems to work fine but I'd still prefer to know why... Does the non-capturing lambda end up defined as some kind of anonymous (hidden) global symbol so it's basically the same as that static function?
#include <cstdio>
class Listener {
public:
void event() { printf("event() called\n"); }
static void forwardEvent(void* userArg) { static_cast<Listener*>(userArg)->event(); }
};
class Producer {
using Listener = void(void* arg);
Listener* listener_;
void* userArg_;
public:
void attachListener(Listener* listener, void* userArg) {
listener_ = listener;
userArg_ = userArg;
}
void issueEvent() { listener_(userArg_); }
};
int main() {
Listener listener;
Producer producer;
{ // different scope, in case that makes a difference...
producer.attachListener(Listener::forwardEvent, &listener);
}
producer.issueEvent();
{ // different scope, in case that makes a difference...
producer.attachListener([](void* userArg) { static_cast<Listener*>(userArg)->event(); }, &listener);
}
producer.issueEvent();
}
Okay, so your nested Listener
definition is this.
using Listener = void(void* arg);
Listener* listener_;
Basically, you deal with good old function pointers. Now when you pass an argument for the function pointer, you do this
producer.attachListener([](void* userArg) { static_cast<Listener*>(userArg)->event(); }, &listener);
The non-capturing lambda is converted to a function pointer via an implicit conversion. This function pointer is
operator()
was called.Functions "exist" for the entire duration of the program, and their addresses never become dangling. So your code has well-defined behavior as far as using the pointer obtained from the lambda expression is concerned.
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