簡體   English   中英

非捕獲 lambda 生命周期

[英]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 通過隱式轉換轉換為函數指針。 這個函數指針是

  1. 保證有效,並指向一個函數
  2. 行為與調用 lambda 的operator()完全相同。

函數在程序的整個持續時間內“存在”,它們的地址永遠不會變成懸空。 因此,就使用從 lambda 表達式獲得的指針而言,您的代碼具有明確定義的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM