shared_ptr + lambda

在C++11裡新支援了lambda, 這也使得編寫C++程式可以多了一些FP的風格。
lambda特別是在處理callback時特別簡潔,因為通常callback function是為了特定api打造的,單獨定義會讓程式碼比較分散,在閱讀上也常會被打斷。

在沒有capture情況下,lambda可以直接當成ordinary function pointer
lambda如果有capture variable, 則可以想像成compiler透過functor的技巧打包,此時不能用在使用function pointer的callback

#include 
typedef 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::function cb);
};

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

This entry was posted in C++ Language. Bookmark the permalink.

Leave a Reply