在lambda中,如何通过值捕获引用

Yur*_*ury 40 c++ c++11

如果引用类型的变量是按值在lambda中捕获的,它是通过引用还是值捕获的?

有问题的小样本:

#include <iostream>

struct Test {
  int a;
};

void testFunc(const Test &test) {
  auto a = [=] {
    // does 'test' is being passed to closure object with copy
    // or by reference?
    return test.a;
  } ();
  std::cout << a;
}

int main() {
  Test test{1};
  testFunc(test);
}
Run Code Online (Sandbox Code Playgroud)

Spo*_*ook 33

按价值.可编辑的例子:

class C
{
public:
    C()
    {
        i = 0;
    }

    C(const C & source)
    {
        std::cout << "Copy ctor called\n";
        i = source.i;
    }

    int i;
};

void test(C & c)
{
    c.i = 20;

    auto lambda = [=]() mutable {

        c.i = 55;
    };
    lambda();

    std::cout << c.i << "\n";
}

int main(int argc, char * argv[])
{
    C c;
    test(c);

    getchar();
}
Run Code Online (Sandbox Code Playgroud)

结果:

Copy ctor called
20

我想,C++标准的这一段适用:

5.1.2 Lambda表达式

(...)14.如果实体被隐式捕获并且捕获默认值为=或者如果使用不包含&的捕获明确捕获实体,则通过副本捕获实体.对于由副本捕获的每个实体,在闭包类型中声明一个未命名的非静态数据成员.这些成员的声明顺序未指定.如果实体不是对对象的引用,则这种数据成员的类型是对应的捕获实体的类型,否则是引用的类型.[ 注意:如果捕获的实体是对函数的引用,则相应的数据成员也是对函数的引用.- 结束说明 ]

这实际上是有道理的 - 如果局部变量通过值传递,参数传递的参数"act"作为函数中的局部变量,为什么它会通过引用而不是值传递?

  • 我认为重要的原因是,只要关闭,变量就是有效的.如果没有剥离引用,这将不起作用. (6认同)
  • 实际原因是 lambda 捕获类型是“推导”的,并且引用被推导为它们的引用类型。有关更多详细信息,请参阅 [`auto`](https://en.cppreference.com/w/cpp/language/auto) 的工作原理。 (3认同)
  • 索赔的任何参考(如规范中的章节和段落编号)? (2认同)