在lambda中按值捕获局部指针,其余按引用捕获

时间:2018-08-12 20:36:41

标签: c++11 lambda

我想在我的lambda表达式中捕获一个本地指针。目前,我的代码看起来像这样

MYButton* button;
button->onPress = [index,&](control*){
            button->foobar(x, y);
    };

我收到错误

  

错误:无法隐式捕获(835,13)变量'button'   在未指定捕获默认值的lambda中

我的印象是,在capture子句中使用&意味着通过引用捕获本地范围内的所有内容。在那种情况下,为什么会出现此错误?

1 个答案:

答案 0 :(得分:4)

未标识任何捕获默认值,因为捕获默认值必须是捕获中的第一项。有关详细信息,请参见cpp reference

正确的代码应该是

MYButton* button;
button->onPress = [&,index](control*){
            button->foobar(x, y);
    };

此外,捕获index似乎没有被使用。您可以消除这种情况,在这种情况下,代码将是

MYButton* button;
button->onPress = [&](control*){
            button->foobar(x, y);
    };

而且,正如克里斯·多德(Chris Dodd)所述,此lambda的使用可能不在此代码片段的范围之内,在这种情况下,您应该按值捕获以避免悬挂引用:

MYButton* button;
button->onPress = [=](control*){
            button->foobar(x, y);
    };

来自cpp reference

  

如果通过引用(隐式或显式)捕获非引用实体,并且在该实体的生命周期结束后调用闭包对象的函数调用运算符,则会发生未定义的行为。 C ++闭包不会延长捕获引用的生存期。

再发表一条评论。尽管默认捕获在纸上看起来不错(一个字符,没有大惊小怪),但我还是想对捕获进行明确说明,以减少发生上述错误的风险。它还使识别lambda依赖于哪些变量变得更加容易。在这种情况下,代码变为:

MYButton* button;
button->onPress = [button](control*){
            button->foobar(x, y);
    };

这只是样式上的更改-它的含义与之前的示例相同,但是在以后修改代码时应避免出错。