68

如果引用类型的变量在 lambda 中按值捕获,则引用的对象是复制还是通过引用捕获?

有问题的小样本:

#include <iostream>

struct Test {
  int a;
};

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

int main() {
  Test test{1};
  testFunc(test);
}
4

1 回答 1

54

按价值。可编译示例:

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();
}

结果:

复制 ctor 调用
20

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

5.1.2 Lambda 表达式

(...) 14. 如果实体被隐式捕获并且捕获默认值为 =,或者如果使用不包含 & 的捕获显式捕获实体,则该实体被复制捕获。对于复制捕获的每个实体,在闭包类型中声明了一个未命名的非静态数据成员。这些成员的声明顺序是未指定的。如果实体不是对对象的引用,则此类数据成员的类型是相应捕获实体的类型,否则是引用的类型。[注意:如果捕获的实体是对函数的引用,则相应的数据成员也是对函数的引用。——<i>尾注]

这实际上是有道理的——如果局部变量是通过值传递的,而通过引用传递的参数“充当”函数中的局部变量,为什么它会通过引用而不是值传递呢?

于 2013-10-30T07:44:58.363 回答