Lambda Captures

Lambda Captures

本文关键字:Captures Lambda      更新时间:2023-10-16

我总是对lambda捕获感到困惑,我不知道变量是通过引用还是值捕获的。例如,如果我有[a]我不知道a是由值还是由引用捕获的。

我认为获得它的简单方法是通过示例。因此,让我们为每个情况提供一个(如果有更多表达相同事物的方式,则更多):

捕获:

  • 全部通过参考
  • 全部按价值
  • r1r2引用。没有别的。
  • v1 ,按值v2。没有别的。
  • r1r2引用。按值休息。
  • v1 ,按值v2。其余按参考。
  • r1,按引用r2v1v2按值。没有别的。

让我们完全忽略this因为那是另一袋蠕虫。

简而言之:

[]{ }          // 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

在 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]{ }

如果要按引用或值有条件地捕获,则可以使用通用 lambda 捕获来实现某种"完美转发捕获":"捕获 lambda 中完美转发的对象"。


让我们完全忽略this因为那是另一袋蠕虫。

[this]{ }  // capture `this` by value (the pointer)
[*this]{ } // store a copy of `*this` inside the closure
  • [*this]于 C++17 年推出。

  • 请注意,[&this]是语法错误。

| 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] |

规则很简单:前面有一个&,通过引用捕获。仅名称,按值捕获。

默认值:按值=全部,&按引用全部。要从"全部"中排除的内容使用上面的简单规则。


完整的规则可以在cpp首选项上阅读。

  • []
    
  • 全部通过参考

    [&]
    
  • 全部按价值

    [=]
    
  • r1r2引用。没有别的。

    [&r1, &r2]
    
  • v1 ,按值v2。没有别的。

    [v1, v2]
    
  • r1r2引用。按值休息。

    [=, &r1, &r2]
    
  • v1 ,按值v2。其余按参考。

    [&, v1, v2]
    
  • r1,按引用r2v1v2按值。没有别的。

    [&r1, &r2, v1, v2]