通过lambda捕获列表中的常量引用传递

P45*_*ent 17 c++ lambda c++11

我正在构建一个lambda函数,需要在上下文中访问相当数量的变量.

const double defaultAmount = [&]{
    /*ToDo*/
}();
Run Code Online (Sandbox Code Playgroud)

我宁愿不在[=]列表中使用,因为我不想要制作很多有价值的副本.

如果我使用,我担心程序稳定性,[&]因为我不希望lambda修改捕获集.

我可以通过const引用吗?[const &]不起作用.

也许一个好的编译器可以优化值副本,因此[=]更可取.

Ant*_*vin 17

您可以显式创建和捕获const引用:

int x = 42;
const int& rx = x;
auto l = [&rx]() {
    x = 5; // error: 'x' is not captured
    rx = 5; // error: assignment of read-only reference 'rx'
};
Run Code Online (Sandbox Code Playgroud)


Nia*_*all 13

捕获列表限制在可捕获的内容中; 基本上按值或按引用(命名或默认),this指针和什么都没有.

cppreference ;

capture-list - 以逗号分隔的零个或多个捕获列表,可选地以capture-default开头.捕获列表可以如下传递(详细说明见下文):

  • [a,&b]其中a按值b捕获并通过引用捕获.
  • [this]this按值捕获指针
  • [&] 通过引用捕获lambda主体中使用的所有自动变量
  • [=] 通过值捕获lambda正文中使用的所有自动变量
  • [] 没有任何东西

您可以const&为要捕获的所有对象创建本地,并在lambda中使用它们.

#include <iostream>

using namespace std;

int main()
{
    int a = 5;
    const int& refa = a;
    const int b = [&]() -> int {
        //refa = 10; // attempts to modify this fail
        return refa;
    }();
    cout << a << " " << b << endl;
}
Run Code Online (Sandbox Code Playgroud)

捕获可以是所有引用,也可以是显式列表所需的内容;

const int b = [&refa]()
Run Code Online (Sandbox Code Playgroud)

另一种选择是根本不捕获局部变量.然后创建一个lambda,它接受您需要的变量作为参数.随着局部变量计数的增长,可能会更加努力,但您可以更好地控制lambda如何接受其参数并能够使用数据.

auto lambda = [](const int& refa /*, ...*/) { */...*/ }
lambda(...);
Run Code Online (Sandbox Code Playgroud)