2015-12-10 71 views
3

有人可以解釋我爲什麼localVar被增加1後重置爲10?看起來lambdas在執行它們之前在堆棧上創建按值捕獲的副本。lambda函數C++通過值捕獲重置其值,爲什麼?

void lambdaTest() 
{ 
    int localVar = 10; 

    // Access all local variables by reference 
    auto byRef = [&]() 
    { 
     cout << "localVar = " << ++localVar << endl; 
    }; 

    // Access all local variables by value 
    auto byValue = [=]() mutable 
    { 
     cout << "localVar = " << localVar << endl; 
    }; 


    byRef();  // localVar = 11 
    byValue();  // localVar = 10, why? 
} 
+4

這些值在定義lambda時捕獲,而不是在使用時捕獲。 –

+0

假設你返回了按值lambda而不是調用它。 'localVar'甚至不存在,因此在使用點捕獲有點棘手。 – chris

回答

3

是的,這正是他們所做的。

Lambdas在內部是operator()爲您設置的結構。當您要求一個lambda按值進行捕獲時,結構會存儲被引用爲結構成員的任何局部變量的副本。因此,你所看到的不是localVar被重置,你看到的lambda的副本localVar

下面是說明這種情況的一個例子:

#include <iostream> 
#include <assert.h> 

int main() 
{ 
    int localVar = 10; 
    auto byRef = [&]() { 
     std::cout << "byRef = " << ++localVar << '\n'; 
    }; 
    auto byValue = [=]() mutable { 
     // `mutable` lets us make changes to the *copy* of `localVar` 
     std::cout << "byVal = " << localVar++ << '\n'; 
    }; 
    byRef(); // byRef = 11 -> actual localVar is now 11 
    byRef(); // byRef = 12 -> actual localVar is now 12 
    byRef(); // byRef = 13 -> actual localVar is now 13 
    byValue(); // byVal = 10 -> copied localVar is now 11 
    byValue(); // byVal = 11 -> copied localVar is now 12 
    assert(localVar == 13); 
} 

Demo

0

添加另一輸出。

void lambdaTest() 
{ 
    int localVar = 10; 

    // Access all local variables by reference 
    auto byRef = [&]() 
    { 
     cout << "localVar = " << ++localVar << endl; 
    }; 

    // Access all local variables by value 
    auto byValue = [=]() mutable 
    { 
     cout << "localVar = " << localVar << endl; 
    }; 


    byRef();  // localVar = 11 
    byValue();  // localVar = 10 
    cout <<localVar << endl; // localVar = 11 
} 

C++ 11當定義lambda時,按值捕獲值,所以lambda沒有改變外部值。

相關問題