可以認為lambda表達式取得信息有兩種方式,或者說兩個時機:一個是參數(shù)列表,其內容是在表達式被調用時決定;另一個捕獲列表,其內容是在是表達式被創(chuàng)建的時候決定,本文討論捕獲列表。
值捕獲
先看如下代碼:
int?factor?=?2; auto?multiply?=?[factor](int?value) ????????????????{return?factor?*?value;}; factor?=?4; cout?<<?multiply(2)?<<?endl;
代碼中首先為factor賦值2,創(chuàng)建lambda表達式以后,再次賦值4。由于lambda表達式的捕獲是在該表達式創(chuàng)建是進行的,而第二次賦值在lambda表達式創(chuàng)建之后,所以muliply(2)的執(zhí)行結果為4。
引用捕獲
還是這段代碼,只要在捕獲列表中變量的前面多了一個&,就變成了引用捕獲。
int?factor?=?2; auto?multiply?=?[&factor](int?value) ????????????????{return?factor?*?value;}; factor?=?4; cout?<<?multiply(2)?<<?endl;
捕獲的時機并沒有變化,只是捕獲的是factor的引用而不是factor的值,所以定義lambda之后,對factor再次賦值4依然會影響multiply(2)的結果。此時的輸出為8。
隱式捕獲
前面例子中使用捕獲列表時,具體指定了變量名,屬于顯式捕獲。另外還有隱式捕獲,由lambda表達式推斷需要捕獲的變量。具體方法是:
當需要隱式值捕獲時,使用[=];
當需要隱式引用捕獲時,使用[&];
在上面例子中使用隱式捕獲以后,結果不會發(fā)生變化。
作者觀點
lambda表達式是個好東西,但也要理解才行。