【问题标题】: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。

      但是,如果您的闭包超出本地范围,& 捕获是不安全的,我什至建议不要使用 = -- 明确捕获,并确保捕获的任何指针都有足够的生命周期。

      特别是对于指针,修改指针与修改指向的数据完全不同。在不修改指针本身的情况下捕获指针的副本不会造成任何问题。

      【讨论】:

        猜你喜欢
        • 2017-10-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多