C ++ 11 lambda:混合捕获列表

时间:2015-08-13 21:19:03

标签: c++ c++11 lambda

有人可以告诉我以下的例子:

1)Lambda按值捕获xy作为参考。如果未指定,其余的默认值是什么?

2)Lambda按值捕获xy引用,其他所有值。

3)Lambda按值捕获xy引用,其他所有参考文献。

此外,允许同一范围内的2个lambda具有相同的捕获签名,例如两者都是[],或者两者都是[& x,=]

由于

4 个答案:

答案 0 :(得分:11)

1)未捕获[x, &y](){}休息

2)[=, &y](){}

3)[&, x](){}

  

捕获列表是以逗号分隔的零个或多个捕获列表,   可选地以capture-default开头。唯一的捕获   默认值是& (通过引用)和=(按值)。如果是捕获默认值   如果使用,其他任何捕获都不能使用相同的捕获类型。任何捕获   可能只出现一次。

此外,是否允许同一范围内的2个lambda具有相同的捕获签名,例如两者都是[],或者两者都是[& x,=]

当然是允许的。每个lambda都是不同的对象,并且具有不同的类型。如果你在两个lambda中按值捕获变量,那么每个lambda都有它的副本。如果您通过引用在两个lambda中捕获变量,那么每个lambda将引用相同的捕获变量。

答案 1 :(得分:7)

可以写一些例子:

int x = 7, y = 12, z = 24;

auto lambda1 = [x, &y]{
    // can't do this...
    // std::cout << "x=" << x << ", y=" << y << ", z=" << z << std::endl;
    std::cout << "x=" << x << ", y=" << y << std::endl;
};

auto lambda2 = [=, x, &y]{
    std::cout << "x=" << x << ", y=" << y << ", z=" << z << std::endl;
};

auto lambda3 = [&, x, &y]{
    std::cout << "x=" << x << ", y=" << y << ", z=" << z << std::endl;
};

++x, ++y, ++z;
lambda1();
lambda2();
lambda3();

现在,lambda1此处无法使用z。没有&#34;隐含&#34;捕获,因为我们没有指定=&z没有出现在捕获列表中,我们无法在那里打印z。如果我们试图使用我已注释掉的那条线,那就错了。

另外两个很好,分别打印7,13,24和7,13,25。请注意,=&必须先行。此外,鉴于我们通过值/引用捕获所有内容,其他捕获之一是多余的,因此我们可以完成:

auto lambda2 = [=, &y]{ ... };
auto lambda3 = [&, x]{ ... };

答案 2 :(得分:2)

1)

[x,&y](){} // the rest is not captured, eg `z` is not defined in the scope

2)

[=,&y](){} // `=` is capture everything by value

3)

[&,x](){} // `&` is capture everything by reference

答案 3 :(得分:1)

从他的C++11 FAQ

中引用Bjarne

[&amp;]是一个&#34;捕获列表&#34;指定使用的本地名称将通过引用传递。我们本可以说我们想要捕捉&#34;只有v,我们可以这么说:[&amp; v]。如果我们想通过值传递v,我们可以这么说:[= v]。什么都不捕获[],通过引用捕获全部是[&amp;],并且按值捕获全部是[=]。 如果一个动作既不常见也不简单,我建议使用一个命名的函数对象或函数。