按價值捕獲

如果在捕獲列表中指定變數的名稱,則 lambda 將按值捕獲它。這意味著為 lambda 生成的閉包型別儲存變數的副本。這也要求變數的型別是可複製構造的

int a = 0;

[a]() {
    return a;   // Ok, 'a' is captured by value
};

Version < C++ 14

auto p = std::unique_ptr<T>(...);

[p]() {         // Compile error; `unique_ptr` is not copy-constructible
    return p->createWidget(); 
};

從 C++ 14 開始,可以在現場初始化變數。這允許僅在 lambda 中捕獲移動型別。

Version >= C++ 14

auto p = std::make_unique<T>(...);

[p = std::move(p)]() {
    return p->createWidget(); 
};

即使 lambda 在按名稱給出時按值捕獲變數,預設情況下也不能在 lambda 體內修改這些變數。這是因為閉包型別將 lambda 主體放在 operator() const 的宣告中。

const 適用於對閉包型別的成員變數的訪問,以及作為閉包成員的捕獲變數(所有外觀相反):

int a = 0;

[a]() {
    a = 2;      // Illegal, 'a' is accessed via `const`

    decltype(a) a1 = 1; 
    a1 = 2; // valid: variable 'a1' is not const
};

要刪除 const,你必須在 lambda 上指定關鍵字 mutable

int a = 0;

[a]() mutable {
    a = 2;      // OK, 'a' can be modified
    return a;
};

因為 a 是按值捕獲的,所以通過呼叫 lambda 進行的任何修改都不會影響 aa 的值在構造時被複制到 lambda 中,因此 a 的 lambda 副本與外部 a 變數分開。

int a = 5 ; 
auto plus5Val = [a] (void) { return a + 5 ; } ; 
auto plus5Ref = [&a] (void) {return a + 5 ; } ; 

a = 7 ; 
std::cout << a << ", value " << plus5Val() << ", reference " << plus5Ref() ;
// The result will be "7, value 10, reference 12"