使用参数lambda函数C ++

时间:2016-10-18 16:57:26

标签: c++ lambda

我有这段代码:

    void function1(char c, bool b){

         auto get_allowed = [&](int x){
                if(b){
                  .... some code...
                }
                ...some code...
         }

         get_allowed(0);
         ...other_code...
}

在这种情况下我可以在lambda函数中使用b ??

我的意思是,将该参数添加到lambda函数的签名中是相同的,例如:

    void function1(char c, bool b){

         auto get_allowed = [&](int x,bool b){
                if(b){
                  .... some code...
                }
                ...some code...
         }

         get_allowed(0, false);
         ...other_code...
}

要澄清,区别在于:

 auto get_allowed = [&](int x){
get_allowed(0);

VS

 auto get_allowed = [&](int x,bool b){
get_allowed(0, false);

其中b是函数function1的参数。

4 个答案:

答案 0 :(得分:2)

在您的示例中,两个版本的lambda的效果大致相同。但是,捕获的参数与“正常”参数之间存在显着差异。

以下是如何创建lambda:

[ capture-list ] ( params ) { body }

capture-list可以让您访问lambda周围范围内的变量。有一些不同的捕获模式:

  • [&]通过引用捕获周围范围内的所有局部变量(例如,示例中的bc
  • [&b]仅通过引用捕获b,您可以根据需要添加任意数量的命名变量(逗号分隔)
  • [=]通过捕获周围范围内的所有局部变量(换句话说:您的lambda包含这些变量的副本)
  • [b]仅通过副本
  • 捕获b
  • [b, &c]您可以混合使用复制和参考捕获

您应该问问自己:这些捕获的内容是什么?

嗯,它定义了一个闭包,一个上下文,每次使用lambda时都是 。在许多情况下,在函数之上添加的那种状态非常有用。

一个例子:您要在集合的每个元素上映射lambda:

std::vector<int> numbers = {1, 2, 3, 4, 5};

int sum = 0;
std::for_each(std::begin(numbers), std::end(numbers),
              [&sum](int n){ sum += n; });

在这里,我们使用通过引用捕获的变量来存储(和更新)向量中所有数字的总和。

花点时间思考这个例子,做一些你自己的实验,这就是关于lambdas的所有知识。 :)

答案 1 :(得分:1)

在第一个示例中,get_allowed是一个参数的函数,其中隐式捕获b(因为您使用[&]捕获)。

在第二个中,get_allowed是两个参数的函数,其中b显式传递给get_allowed而不是从周围函数中获取。

在这个例子中,lambda是不必要的,因此差异有点学术性。

答案 2 :(得分:1)

[&]捕获列表确保lambda定义范围内的变量可以在lambda函数的主体中通过引用使用。

所以是的:在第一个片段中,b在lambda中可用(只是不要忘记半列来结束函数赋值)。您甚至可以更改其值(在b中影响get_allowed()会更改b的参数function1()的值,因为它是通过引用捕获的)!

在第二个代码段中,您将b作为参数传递给值。这工作方式不同。 b是通过值传递的参数的名称,它与封闭范围的b无关。

补充说明

注意:如果你的lambda在定义它的范围内存活(例如,如果你从function1()返回lambda或存储get_allowed的值),你可能会遇到捕获问题引用 ;稍后在另一个上下文中调用lambda可以引用不再存在的变量(悬空引用)。

如果您更喜欢松散耦合,您可以考虑使用[=]捕获列表:它具有类似的效果,但捕获的变量按值传递(即没有意外修改也没有悬挂引用)。这使得lambda更加独立于创建它的上下文。

答案 3 :(得分:1)

  

在这种情况下我可以在lambda函数中使用b ??

是的,您可以在lambda中使用b

  

[&amp;] captures所有通过引用在lambda正文中使用的自动变量

b由参考

捕获