简体   繁体   English

使用参数lambda函数C ++

[英]Use parameter lambda function C++

I have this piece of code: 我有这段代码:

    void function1(char c, bool b){

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

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

Can I use b inside the lambda function in this case?? 在这种情况下,我可以在lambda函数中使用b吗?

I means, is the same thing to add that parameter into signature of lambda function, something like: 我的意思是,将该参数添加到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...
}

To clearify, the difference is here: 为了澄清,区别在这里:

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

VS VS

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

where b is a parameter of the function function1. 其中b是函数function1的参数。

In your example, the effect of both version of you lambda is roughly the same. 在您的示例中,两个版本的lambda的效果大致相同。 However, there is a significant difference that lies in captured parameters vs "normal" parameters . 但是, 捕获的参数与“正常”参数之间存在显着差异。

Here is how a lambda is created: 这是lambda的创建方式:

[ capture-list ] ( params ) { body }

The capture-list can give you access to variables that exist in the scope surrounding your lambda. capture-list可让您访问lambda范围内存在的变量。 There are some of the different capture modes: 有一些不同的捕获模式:

  • [&] captures by reference all local variables in the surrounding scope (ie. b and c in your example) [&]通过引用捕获周围范围内的所有局部变量(即示例中的bc
  • [&b] captures only b by reference, you can put as many named variables as you wish (comma separated) [&b]仅通过引用捕获b ,您可以根据需要放置任意数量的命名变量(逗号分隔)
  • [=] captures by value all local variables in the surrounding scope (in other words: your lambda holds a copy of those variables) [=]通过捕获周围范围内的所有局部变量(换句话说:您的lambda拥有这些变量的副本)
  • [b] captures only b by copy [b]仅捕获副本b
  • [b, &c] you can mix copy and reference captures [b, &c]您可以混合使用副本和参考捕获

You should ask yourself : what are those captures for? 您应该问自己: 这些捕获是为了什么?

Well, it defines a closure , a context , which is the same each time the lambda is used . 好吧,它定义了一个闭包 ,一个上下文每次使用lambda时都是相同的 That kind of state added on top of a function is very useful in many situations. 在许多情况下,添加到函数顶部的这种状态非常有用。

One example: you are mapping a lambda on each element of a collection: 一个示例:您正在将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; });

Here, we are using a variable captured by reference to store (and update) the sum of all the numbers in the vector. 在这里,我们使用通过引用捕获的变量来存储(和更新)向量中所有数字的总和。

Take some time to reflect on this example, make some experiments of your own, and this is about all there is to know about lambdas. 花一些时间思考一下这个示例,自己做一些实验,这就是关于lambda的所有知识。 :) :)

In the first example get_allowed is a function of one argument where b is captured implicitly (because you captured with [&] ). 在第一个示例中, get_allowed是一个参数的函数,其中b是隐式捕获的(因为您是使用[&]捕获的)。

In the second, get_allowed is a function of two arguments where b is passed explicitly to get_allowed rather than taken from the surrounding function. 在第二个中, get_allowed是两个参数的函数,其中b显式传递给get_allowed而不是从周围的函数中获取。

The lambda is unnecessary in this example so the difference is a bit academic. 在此示例中,lambda是不必要的,因此差异有些学术性。

The [&] capture list makes sure that the variables in the scope surrounding the definition of the lambda can be used by reference in the body of the lambda function. [&]捕获列表确保lambda定义范围内的变量可以通过lambda函数主体中的引用来使用。

So yes: in the first snippet, b is usable in the lambda (just don't forget the semi-column to end the function assignment). 所以是的:在第一个代码段中, b在lambda中可用(只是不要忘记半列来结束函数赋值)。 And you even can change its value (affecting b in get_allowed() would change the value of the parameter b of function1() as it is captured by reference) ! 您甚至可以更改其值(在get_allowed()影响b会更改function1()的参数b的值,因为它被引用捕获了)!

In the second snippet, you pass b as parameter by value. 在第二个片段中,按值传递b作为参数。 This works differently. 这是不同的。 There b is the name of a parameter passed by value, and it has nothing to do with the b of the enclosing scope. b是按值传递的参数的名称,它与封闭范围的b没有关系。

Additional remarks 补充说明

Attention: if your lambda survives the scope that defines it (for example, if you'd return the lambda from function1() or store the value of get_allowed ), you could have problems with a capture by reference ; 注意:如果您的lambda保留了定义它的范围(例如,如果您要从function1()返回lambda或存储get_allowed的值), get_allowed引用捕获可能会出现问题; invoking the lambda later in another context could reference variables which no longer exist (dangling reference). 稍后在另一个上下文中调用lambda可以引用不再存在的变量(悬挂引用)。

If you prefer a looser coupling, you may consider the [=] capture list instead: it has a similar effect, but the captured variables are passed by value (ie no accidental modification nor dangling references). 如果您更喜欢宽松的耦合,则可以考虑使用[=]捕获列表:它具有类似的效果,但是捕获的变量按值传递(即,无意修改也没有悬挂引用)。 This makes the lambda more independent the context in which it was created. 这使lambda在创建它的上下文中更加独立。

Can I use b inside the lambda function in this case?? 在这种情况下,我可以在lambda函数中使用b吗?

Yes, you can use b inside the lambda. 是的,您可以在lambda中使用b

[&] captures all automatic variables odr-used in the body of the lambda by reference [&]通过引用捕获在lambda主体中奇数使用的所有自动变量

b is captured by reference b被引用捕获

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM