[英]Non-capturing lambda lifecycle
如果以下代碼在兩種情況下都是正確的,無論是非捕獲 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 表達式獲得的指針而言,您的代碼具有明確定義的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.