Post

Lambda and std::function

Lambda的生命周期

正常来讲, lambda的所capture的值如果是引用的话, 需要注意一下生命周期的问题。

保证lambda不要获得比这些引用捕获的值长。

在debug一次crash的时候, 发现了一个和lambda生命周期有关的bug

1
2
3
4
5
6
7
[weak_ptr_, cb](int, vector<string>) {
  if (cb)  {
    cb(); // 这个cb可能会设置这个lambda为nullptr
  }
  weak_ptr_.lock();
  ...
}

这个lambda是被保存在一个对象的function中的, 在cb执行中,可能导致这个lambda的function被置为nullptr。 比较trick的是, 这个function被置为nullptr之后,*this没有意义了, 开始析构, 当前lambda所捕获的变量就会被销毁, 所以后续执行到的跟捕获有关的代码, 都是heap use after free的。

lambda和bind到function

简而言之,lambda的仿函数是自己写的,bind的会留指针,在operator()里调用

所以bind type至少需要1指针的空间

std::funciton里一般都是4指针大小的空间,里面可能类似短字符串优化这种成员函数指针placement new的东西,当需要转过去的callable比较小的时候就不用new一段内存出来

所以针对c++14而言,lambda能用的地方,bind都能用,建议用lambda,尤其是需要转function的时候,这样如果不过的东西足够少的话,其实可以有效的减少new/delete

另外找到了部分ref,还没细看, 主要讲的是不要用std::function, 用模板来代替, 这样可以避免一些不必要的开销,实名diss我司架构师,他写的lambda真的用std::function做callable。。。

Ref

  1. Avoiding The Performance Hazzards of std::function

  2. Is it possible to figure out the parameter type and return type of a lambda

  3. Lambda, bind(front), std::function, Function Pointer Benchmarks

  4. 关于std function和lambda function的性能调试

  5. std function是怎么做到在不使用虚函数的情况下,保存,复制和移动lambda的?

This post is licensed under CC BY 4.0 by the author.

Trending Tags