如果以下代码在两种情况下都是正确的,无论是非捕获 lambda 还是调用静态函数,我都很难找到明确的答案。我很确定后者很好,我担心的是在另一个块/函数调用中“定义”时 lambda 的生命周期,等等。代码似乎工作正常,但我仍然想知道为什么...非捕获 lambda 最终是否被定义为某种匿名(隐藏)全局符号,因此它与该静态函数基本相同?
#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();
}
最佳答案
好的,所以你的嵌套 Listener
定义是这样的。
using Listener = void(void* arg);
Listener* listener_;
基本上,您处理的是好的旧函数指针。现在,当您为函数指针传递参数时,您可以这样做producer.attachListener([](void* userArg) { static_cast<Listener*>(userArg)->event(); }, &listener);
非捕获 lambda 通过隐式转换转换为函数指针。这个函数指针是operator()
完全相同被称为。 函数在程序的整个持续时间内“存在”,它们的地址永远不会变成悬空。因此,就使用从 lambda 表达式获得的指针而言,您的代码具有明确定义的行为。
关于c++ - 非捕获 lambda 生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64159461/