简体   繁体   English

Lambda捕获

[英]Lambda Captures

I always get confused by the lambda capture and I don't know if a variable is captured by reference or by value. 我总是对lambda捕获感到困惑,我不知道变量是通过引用还是通过值捕获的。 For instance if I have [a] I don't know if a is captured by value or by ref. 例如,如果我有[a]我不知道a是通过值还是通过ref捕获的。

I think a simple way to get it would be by examples. 我认为一个简单的方法就是通过例子。 So let's have one for each of the cases (more if there are more ways of expressing the same thing): 因此,让每个案例都有一个案例(如果有更多表达同一事物的方式,则更多):

Capture: 捕获:

  • nothing 没有
  • all by reference 全部参考
  • all by value 所有的价值
  • r1 , r2 by reference. r1r2作为参考。 Nothing else. 没有其他的。
  • v1 , v2 by value. v1v2按值。 Nothing else. 没有其他的。
  • r1 , r2 by reference. r1r2作为参考。 Rest by value. 按价值休息。
  • v1 , v2 by value. v1v2按值。 Rest by reference. 通过参考休息。
  • r1 , r2 by reference, v1 , v2 by value. r1r2为参考, v1v2为值。 Nothing else. 没有其他的。

Let's completely ignore this as that is another bag of worms. 让我们完全忽略this因为那是另一袋蠕虫。

In short: 简而言之:

[]{ }          // do not capture anything
[foo]{ }       // capture `foo` by value
[&foo]{ }      // capture `foo` by reference
[foo, &bar]{ } // capture `foo` by value, `bar` by reference
[=, &foo]{ }   // capture everything by value, `foo` by reference
[&, foo]{ }    // capture everything by reference, `foo` by value

In C++14, you also have generalized lambda captures : 在C ++ 14中,您还有一般化的lambda捕获

[i=0]{ }  // create closure with `i` data member initialized to `0`
[i=j]{ }  // create closure with `i` data member initialized to `j`
[i{0}]{ } // create closure with `i` data member initialized to `0`
[i{j}]{ } // create closure with `i` data member initialized to `j`

// create closure with `uptr` data member initialized to `std::move(uptr)`
[uptr = std::move(uptr)]{ } 

// create closure with `foo` reference data member initialized to `something`
[&foo = something]{ }

If you want to conditionally capture either by reference or by value, you can use generalized lambda captures to implement some sort of "perfect-forwarding capture": "capturing perfectly-forwarded objects in lambdas" . 如果要通过引用或值有条件地捕获,可以使用通用lambda捕获来实现某种“完美转发捕获”: “捕获lambdas中完美转发的对象”


Let's completely ignore this as that is another bag of worms. 让我们完全忽略this因为那是另一袋蠕虫。

[this]{ }  // capture `this` by value (the pointer)
[*this]{ } // store a copy of `*this` inside the closure
| Capture                                       | Syntax             |
| --------------------------------------------- | ------------------ |
| nothing                                       | []                 |
| all by reference                              | [&]                |
| all by value                                  | [=]                |
| r1, r2 by reference. Nothing else.            | [&r1, &r2]         |
| v1, v2 by value. Nothing else.                | [v1, v2]           |
| r1, r2 by reference. Rest by value.           | [=, &r1, &r2]      |
| v1, v2 by value. Rest by reference.           | [&, v1, v2]        |
| r1, r2 by ref, v1, v2 by value. Nothing else. | [v1, v2, &r1, &r2] |

The rule is simple: preceded by an & , capture by reference. 规则很简单:以&开头,以引用方式捕获。 Name only, capture by value. 仅限名称,按值捕获。

Defaults: = all by value, & all by reference. 默认值: =所有值, &全部通过引用。 Things to exclude from "all" use the simple rule above. 要从“所有”中排除的东西使用上面的简单规则。


The full rules can be read on cppreference . 可以在cppreference上读取完整规则。

  • nothing 没有

     [] 
  • all by reference 全部参考

     [&] 
  • all by value 所有的价值

     [=] 
  • r1 , r2 by reference. r1r2作为参考。 Nothing else. 没有其他的。

     [&r1, &r2] 
  • v1 , v2 by value. v1v2按值。 Nothing else. 没有其他的。

     [v1, v2] 
  • r1 , r2 by reference. r1r2作为参考。 Rest by value. 按价值休息。

     [=, &r1, &r2] 
  • v1 , v2 by value. v1v2按值。 Rest by reference. 通过参考休息。

     [&, v1, v2] 
  • r1 , r2 by reference, v1 , v2 by value. r1r2为参考, v1v2为值。 Nothing else. 没有其他的。

     [&r1, &r2, v1, v2] 

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

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