2017-08-29 86 views
3

這似乎很奇怪,我可以捕獲靜態變量,但前提是該變量未在捕獲列表中指定,即隱式捕獲它。無法捕捉到一個lamba中的靜態變量

int main() 
{ 
    int captureMe = 0; 
    static int captureMe_static = 0; 

    auto lambda1 = [&]() { captureMe++; }; // Works, deduced capture 
    auto lambda2 = [&captureMe]() { captureMe++; }; // Works, explicit capture 
    auto lambda3 = [&]() { captureMe_static++; }; // Works, capturing static int implicitly 
    auto lambda4 = [&captureMe_static] { captureMe_static++; }; // Capturing static in explicitly: 
                   // Error: A variable with static storage duration 
                   // cannot be captured in a lambda 

    // Also says "identifier in capture must be a variable with automatic storage duration declared 
    // in the reaching scope of the lambda 

    lambda1(); lambda2(); lambda3(); // All work fine 

    return 0; 
} 

我不理解,第三個和第四個捕獲應該是等價的,不是?第三,我沒有捕捉變量與「自動存儲時間」

編輯:我認爲這個問題的答案是,這是從來沒有捕獲靜態變量,所以:

auto lambda = [&] { captureMe_static++; }; // Ampersand says to capture any variables, but it doesn't need to capture anything so the ampersand is not doing anything 
auto lambda = [] { captureMe_static++; }; // As shown by this, the static doesn't need to be captured, and can't be captured according to the rules. 
+0

([通過在C++ 11拉姆達參考捕捉靜態變量]的可能的複製https://stackoverflow.com/questions/13827855/capturing-a-static-variable-by-reference-in -a-c11-lambda) –

回答

6

具有可變靜態存儲時間不需要被捕獲,因此不能被捕獲。你可以簡單地在lambda中使用它。

使用自動變量存在一個問題:在其他語言中,閉包會簡單地在封閉範圍中存儲對變量的引用,在C++中,lambda不具有延長自動變量生命週期的能力,因此可能會超出範圍,在lambda中留下一個懸而未決的參考。爲此,C++允許您選擇是通過複製還是通過引用來捕獲自動變量。但是如果變量是靜態的,那麼這個問題就不會出現;拉姆達只會表現得像通過引用捕獲它一樣。

如果您確實想要通過捕獲靜態變量,請使用C++ 14 init-capture語法。

+0

「不需要被捕獲,因此不能被捕獲。」 我在這裏看不到邏輯。爲什麼禁止顯式靜態變量捕獲,如果它無縫地適合C++語言規則 –

+0

@ sfk92fksdf我無法告訴你。委員會中的某個人可能會知道答案。 – Brian

+1

@ sfk92fksdf有你正在尋找的答案:https://stackoverflow.com/a/13828144/2865757 – Zefick

0

這不是你想要的嗎?

static int dont_capture_me = 0; 

auto foo = [] { dont_capture_me++; }; 

當然,你可以明確地存儲一個引用,但它們本質上是等價的。

auto bar = [&reference = dont_capture_me] { reference++; };