【问题标题】:C++ lambda. How need to capture the pointer?C++ 拉姆达。如何需要捕获指针?
【发布时间】:2014-04-19 19:24:32
【问题描述】:
比如有一个方法:
void foo( A* p )
{
auto l = [=](){ /* Do Something using p */ };
// Use l ...
}
我应该如何捕获指针:通过引用还是通过值?
内部 lambda p 没有改变,只是使用了它的方法。
【问题讨论】:
标签:
c++
c++11
pointers
lambda
object-lifetime
【解决方案1】:
它是一个指针这一事实不会影响您对 ref 或值捕获的决定。由于指针足够小,不想写,可以按值捕获。
我通常使用以下规则:
- 如果它比指针大,请使用引用,因为复制可能比取消引用更昂贵
- 如果您想从 lambda 外部查看更改,显然引用是唯一的选择
- 否则(如果它很小且不变)按值捕获
所以一个不改变的指针应该被值捕获。如果编译器检测到没有写入,它可能会通过引用优化捕获并通过值传递,但我不确定。
【解决方案2】:
指针没有方法(或者,在 C++ 术语中,成员函数)。您可能的意思是您只调用p 指向的对象的成员函数。因此,如果不想影响p本身,就没有必要通过引用来捕获它。因此,只需按价值捕获它,就像您现在所做的那样。
【解决方案3】:
如果您有一个真正的本地 lambda(其生命周期不超过其范围),[&] 捕获通常是无害的。在许多情况下,引用可以被相当聪明的编译器视为纯别名,它使 ot 的行为类似于“本地函数”。
如果您的本地范围内有很多状态,有时准确描述您捕获的内容
好的。并且 = 在具有琐碎副本的小型廉价对象(如 int 或指针)上也可以像别名一样对待,尤其是对于非 mutable lambdas。
但是,如果您的闭包超出本地范围,& 捕获是不安全的,我什至建议不要使用 = -- 明确捕获,并确保捕获的任何指针都有足够的生命周期。
特别是对于指针,修改指针与修改指向的数据完全不同。在不修改指针本身的情况下捕获指针的副本不会造成任何问题。