C ++ lambda。如何捕获指针?

时间:2014-03-14 13:16:39

标签: c++ c++11 pointers lambda object-lifetime

例如,有一种方法:

void foo( A* p )
{
    auto l = [=](){ /* Do Something using p */ };

   // Use l ...
}

我应该如何捕获指针:通过引用或值? 里面的lambda p没有改变,只是使用了它的方法。

3 个答案:

答案 0 :(得分:5)

它是指针这一事实不会影响您对ref或值捕获的决定。由于指针足够小并且您不想写它,您可以按值捕获。

我通常使用以下规则:

  • 如果它比指针大,请使用引用,因为复制可能比取消引用更昂贵
  • 如果你想看看lambda外部的变化,显然引用是唯一的选择
  • 否则(如果它很小而且没有变化)按值捕获

因此,应该通过值捕获不会发生变化的指针。如果编译器检测到没有写入,它可能会通过引用优化捕获并且仍然按值传递,但我不确定。

答案 1 :(得分:3)

指针没有方法(或者,在C ++术语中,成员函数)。您可能意味着您只调用p指向的对象的成员函数。因此,如果您不想影响p本身,则无需通过引用来捕获它。所以,就像现在一样按价值捕捉它。

答案 2 :(得分:2)

如果你有一个真正的本地lambda - 一个寿命不超过其范围的lambda - [&]的capturimg通常是无害的。在许多情况下,可以通过合理的智能编译器将引用视为纯别名,并且它使得行为类似于本地函数'会。

如果本地范围内有很多状态,有时会准确描述您捕获的内容  好。对于具有普通副本的小型廉价对象(如=或指针)上的int也可以被视为别名,尤其是对于非mutable lambdas。

但是,如果你的闭包超过了局部范围,&捕获是不安全的,我甚至会建议反对= - 明确捕获,并确保捕获的任何指针都有足够的生命周期。

特别是对于指针,修改指针与修改指向的数据完全不同。当你不修改指针本身时捕获指针的副本不会导致任何问题。