Reference
Lambdas is just a Class
Lambdas 的實現原理就是 compiler 幫你把他轉成一個 Class 而已,考慮以下的例子:
我們可以用一個 class 做到完全相同的事情,這裡我們透過 cppinsight 來觀察上面的 lambdas function 會被 compiler 轉換成什麼:
可以看到 compiler 其實只是將 lambdas function 的 capture list 裡面的 variable 換成 class 的 private member variable,然後 overload operator()
,所以當 __lambda_1_12{10}
被建立出來並 assign 給 foo
後,若 foo()
被執行,其實就是呼叫了被 overload 的 ()
operator。
A weird way to print out hello world.
什麼時候 IIFE 有用?看下面的例子,若今天要 initialize foo
的 if else 的判斷很複雜,通常我們就會想要抽 function,但是這樣就必須把 if else 要判斷的任何參數從 local 傳進 function parameter,而 lambda 可以直接 capture 這些必要的參數,且將判斷邏輯留在 local,在 trace code 時更好被理解。
如果覺得 ()
invoke lambda function 的方式不太明顯,看的人會誤會的話,可以使用 std::invoke
:
Capture List
為何一個會印出 11 一個則是 21?我們一樣透過 cppinsight 來觀察:
可以觀察到 bar
在 class 被 initialize 時,global 的 g
有被當作參數傳進他的 constructor,而 foo
則沒有。
在 class foo
會在執行當下抓目前的 g
是多少,因此會抓到 20
。
Static Variable in lambdas
lambdas 的 static variable 和一般的 function static variable 不一樣!說到底還是因為 lambdas 的底層是 class!
因為 i
是同一個 class 的 static member,而 c1 & c2 是同一個 lambdas,因此對應到同一個 class。
使用 cppinsights 觀察可以更加得清楚,底下是 compiler 針對上面的 code 所產生的。
注意到 compiler 會將 operator()()
設為 const!
也因此,若想要改變 i 的值,就必須 specify mutable
!
Lambdas is constexpr by default
Generic Lambdas
Which is just templates under the hood.
Using cppinsights again, and there it is, the templates.
“this” in lambda
In lambda, the this keyword does not mean the lambda itself, but whatever the lambda is used on. This is a designed choice:
In the above example, if this refers to the lambda itself, we’re in trouble.
the unary operatoron lambdas
don’t use this in production code!
因為 unary operator 只作用在 pointer type 上,所以 compliler 會幫我們把 lambdas 轉成 pointer to function,而 + 在 function pointer 上等於 nop。
Only Called Once