在C++11裡新支援了lambda, 這也使得編寫C++程式可以多了一些FP的風格。
lambda特別是在處理callback時特別簡潔,因為通常callback function是為了特定api打造的,單獨定義會讓程式碼比較分散,在閱讀上也常會被打斷。
在沒有capture情況下,lambda可以直接當成ordinary function pointer
lambda如果有capture variable, 則可以想像成compiler透過functor的技巧打包,此時不能用在使用function pointer的callback
#includetypedef void (*callback)(int); void test(callback cb) { cb(100); } int main() { //capture-less lambda, can be treated like function pointer test([](int n){ std::cout << "in lambda, " << n << std::endl; }); return 0; }
沒有capture variable的lambda function,使用上不需注意太多。但是如果有capture variable,那要特別注意變數生命週期的問題。
第一件事是要先確定該callback是synchronous or asynchronous,synchronous的情況一般也不太會有問題,但asynchronous callback很容易遇到當callback回來時,物件不知道是否仍存在
一個典型的例子是 tcp connection, 在收到資料後回調callback,
class Connection { ... void read(std::functioncb); }; conn->read([conn](int len, char* buffer){ //check len, if <0, error case //process something //start another read });
這邊要注意conn存在時間要足夠長,為了避免手動管理物件的存在時間,可以考慮使用shared_ptr
"假如" conn是shared_ptr,以上的code可以直接確保conn一定會在callback時還活著
lamba object因為capture conn, 在執行到read該處時,conn會被複製進lambda object
從而使reference count + 1