lambda表達式的捕獲跟參數差不多,可以是值或者引用。
1.值捕獲
與傳值參數類似,采用值捕獲的前期是變量可以拷貝;與參數不通透的是:被捕獲的變量的值是在lambda創建時拷貝,而不是調用時拷貝。
void func(){ int v1 = 1; auto f = [v1] { return v1;}; v1 = 0; auto j = f(); //j為1;f保存了我們創建它時v1的拷貝 }
2.引用捕獲
在使用引用捕獲的時候,由於lambda保存的是引用,因此值會隨着引用變化而變化。
void func(){ int v1 = 1; auto f = [&v1] { return v1;}; v1 = 0; auto j = f(); //j為0;f保存的是v1的引用,而非拷貝 }
在以上兩種捕獲的方式中,都有着相同的問題和限制:lambda捕獲的是局部變量,如果lambda在函數結束后執行,那么這些局部變量就都消失了。
除了上面兩種捕獲之外,我們還可以采用隱式捕獲。
3.隱式捕獲
為了指示編譯器推斷捕獲列表,我們可以在捕獲列表中寫一個&或=。&告訴編譯器采用引用捕獲,=則為值捕獲方式。如:
auto f = [&] {return v1}; auto f = [=] {return v1};
除了&與=,還有以下的捕獲列表
[] 空捕獲列表
[names] names是一個逗號分隔的名字列表,默認全部都被拷貝
[&] 引用捕獲
[=] 值捕獲
[&,identifier_list] identifier_list為一個逗號分隔的列表,包含多個來自函數的變量,均采用值捕獲方式,而任何隱式捕獲的變量都采用引用捕獲的方式
[=,identifier_list] identifier_list為一個逗號分隔的列表,包含多個來自函數的變量,均采用引用捕獲方式,而任何隱式捕獲的變量都采用值捕獲的方式