在lambda中的分配

Dea*_*ean 15 c++ lambda

我正在查看以下(可能是C++ 14)代码

auto min_on = [](auto&& f) {
  return [f=decltype(f)(f)](auto&& arg0, auto&&...args) {
    // call your function here, using decltype(args)(args) to perfect forward
  };
}
Run Code Online (Sandbox Code Playgroud)

lambda捕获列表中奇怪的赋值是什么?我从未在捕获列表中看到过任务

f=decltype(f)(f)
Run Code Online (Sandbox Code Playgroud)

这是如何运作的?

And*_*dyG 16

这就是所谓的广义Lambda Capture,是的,它是C++ 14.

基本上它允许您创建一个新变量作为捕获列表的一部分.

链接文字:

在C++ 11中,lambdas无法(轻松)通过移动捕获.在C++ 14中,我们推广了lambda捕获,它不仅解决了这个问题,还允许您在lambda对象中定义任意新的局部变量.例如:

auto u = make_unique<some_type>( some, parameters );  // a unique_ptr is move-only
go.run( [ u=move(u) ] { do_something_with( u ); } ); //move the unique_ptr into the lambda 
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我们u在lambda中保持变量的名称相同.但我们不仅限于此......我们可以重命名变量:

go.run( [ u2=move(u) ] { do_something_with( u2 ); } ); // capture as "u2"
Run Code Online (Sandbox Code Playgroud)

我们可以向lambda对象添加任意新状态,因为每个捕获在lambda中创建一个新的类型推导的局部变量:

int x = 4; 
int z = [&r = x, y = x+1] {
            r += 2;         // set x to 6; "R is for Renamed Ref"
            return y+2;     // return 7 to initialize z
        }(); // invoke lambda
Run Code Online (Sandbox Code Playgroud)

在您的特定实例中,您有一个返回lambda的lambda.嵌套的lambda f通过使用这种新语法捕获(它只是父lambda中的一个参数).

  • 我想补充说,在这种情况下,`decltype(f)(f)`是一种编写`std :: forward <T>(f)`的方法,因为你实际上不能命名`T`. (3认同)
  • @Brian`std :: forward <decltype(f)>(f)`会更好地表达意图. (2认同)