C/C++:lambda

一篇極好的文章,建議直接轉到 https://shaharmike.com/cpp/lambdas-and-functions/

然後...再多說一點,lambda表達式只要沒有最後表示執行的括號,其實就是一個對象,如下

int main()
{
    int  a;
    int  b;
    char c;
    char d;
    auto func = [&a, b, &c, d ](int i, int j){std::cout << i+j << std::endl;};

    // 錯誤,func不是一個函數指針
    void (*q)();
    q = func;

    // 正確,將void類型指針指向func對象地址並調用,結果輸出3
    void* p = &func
    (*p)(1, 2);
}

 [...] 中捕獲的變量或者引用其實是對象中的成員變量(引用會成爲成員變量嗎?經測試得到引用被捕獲之後佔用空間大小表現爲指針的特性),測試如下。

int main()
{
    int  a;
    int  b;
    char c;
    char d;
    auto func = [&a, b, &c, d](int i, int j){};
    
    std::cout << sizeof(func) << std::endl;
}
// 輸出結果是32


int main()
{
    int  a;
    int  b;
    char c;
    char d;
    auto func = [a, b, &c, d](int i, int j){};
    
    std::cout << sizeof(func) << std::endl;
}
// 輸出結果是24


int main()
{
    int  a;
    int  b;
    char c;
    char d;
    auto func = [c, d, a, b](int i, int j){};
    
    std::cout << sizeof(func) << std::endl;
}
// 輸出結果是12

由此可以看出,lambda對象中成員變量的內存佈局(引用變量表現爲指針),其實是按照普通結構體字節碼對其的規則劃分的。

我的一個猜測:lambda表達式捕獲的變量或者引用只能具有局部生命週期(也就是說只能捕獲函數裏面的局部變量),因此lambda表達式的對象在是在函數裏面實例化的(也就是存在於在棧內存中),而lambda表達式傳入的參數也是在棧上,所以lambda表達式捕獲的變量和給它傳入的參數在同一塊存儲區域內。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章