簡體   English   中英

C ++ lambda中的靜態變量

[英]Static variables in C++ lambdas

以下代碼工作正常:

#include <iostream>
#include <functional>

std::function<int (void)> get_incrementer() {
    return []() {
        static int count = 0;
        return count++;
    };
}

int main() {
    using std::cout;

    auto incrementer = get_incrementer();

    cout << incrementer() << std::endl;
    cout << incrementer() << std::endl;

    return 0;
}

但是,如果您通過引用捕獲局部變量,它會突然導致未定義的行為,因為在調用時,堆棧上的位置正被其他東西使用。

std::function<int (void)> get_incrementer() {
    int count = 0;

    return [&count]() {
        return count++;
    };
}

為什么編譯器允許它呢? 我希望編譯器要么不允許這樣做(檢查這種情況似乎微不足道)或者改變局部變量的存儲持續時間。

C ++允許它,因為C ++不是一種安全的語言。 雖然這個案例可能是“微不足道”來檢查(而且個人而言,我不同意這是微不足道的,但我不是編譯器編寫者),還有很多其他案例並不容易檢查。

C ++不是為您修復損壞的代碼。 它確實只是你告訴它的,即使它是非常不明智的。

此外,還不完全清楚你打算用這個代碼做什么。 例如,這些是完全不同的兩件事:

std::function<int (void)> get_incrementer() {
    return []() {
        static int count = 0;
        return count++;
    };
}

std::function<int (void)> get_incrementer() {
    int count = 0;
    return [count]() mutable {
        return count++;
    };
}

在第一種情況下,返回函數的每個實例將共享相同的增量計數。 在第二種情況下,每次調用get_incrementer ,您將獲得一個單獨的對象,其中包含自己的增量計數。

用戶想要哪一個? 目前尚不清楚。 所以你不能隨便“糾正”它。

您明確告訴編譯器您希望通過引用獲取變量,因此它假定您有自己的理由並按照您的要求執行操作。

您是主人,編譯器只是滿足您的需求並遵守您的意願。 它可能會在某些情況下警告你,當它認為你正在做一些特別奇怪的事情時,但是如果你堅持,它會尊重你的權威並編譯那些奇怪的代碼。

在局部變量超出范圍之后使用對局部變量的引用總是未定義的行為並且不會有任何好處,使用lambda來完成它並不是那么特別。

暫無
暫無

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

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