为什么我需要设置lambda捕获?

时间:2018-01-18 11:39:45

标签: c++11 lambda

我没有太多使用lambda的经验 - 我希望有人可以用“外行人的条款”(如果可能的话)解释我在下面所做的事情。

我有一个std::vector有许多对象(或没有)。每个对象都有一个id。我想将带有我感兴趣的id的对象放在向量的后面。

我是这样做的

std::vector<my_ob> l_obs;

[...] // populate the vector

auto l_elem = std::find_if(l_obs.rbegin(), 
  l_obs.rend(), [](my_ob const& ob){ return ob.mv_id == 8;});

if(l_elem-l_obs.rbegin())
  std::iter_swap(l_elem, l_obs.rbegin());

我正在使用反向迭代器,因为我希望在大多数情况下匹配已经位于向量的后面。

以上工作正常,直到我将其移动到方法中,而不是试图找到'8',我想找到一个作为const int参数传递的值。编译器告诉我,我没有捕获我使用的参数,并且lambda没有捕获默认值。所以我将lambda改为

[=](my_ob const& ob){ return ob.mv_id == _arg;}

现在这一切似乎都有效。

为什么需要这个=符号?

1 个答案:

答案 0 :(得分:2)

Lambda表达式生成闭包对象,它们是函数对象(类似于struct,带有重载operator())。

为了使闭包在外部作用域中使用变量,它们必须知道如何:通过将变量复制到闭包本身,或者通过引用它。

书写

[=](my_ob const& ob){ return ob.mv_id == _arg;}

相当于

[_arg](my_ob const& ob){ return ob.mv_id == _arg;}

大致贬低

struct LAMBDA 
{
    int _arg;
    LAMBDA(int arg) : _arg{arg} { }

    auto operator()(my_ob const& ob) const { return ob.mv_id == _arg; }
};

如您所见,_arg需要在生成的LAMBDA函数对象的范围内可用,因此它需要是闭包的数据成员。

当您使用文字时,不需要捕获,因为生成的闭包看起来像:

struct LAMBDA 
{
    auto operator()(my_ob const& ob) const { return ob.mv_id == 5; }
};