代码之家  ›  专栏  ›  技术社区  ›  Rajeshwar

在lambda中按值捕获本地指针,其余按引用捕获

  •  0
  • Rajeshwar  · 技术社区  · 7 年前

    我想在lambda表达式中捕获一个本地指针。当前我的代码如下所示

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

    我明白错误

    错误:(835,13)无法隐式捕获变量“button”

    我的印象是 & 在capture子句中,意味着通过引用捕获本地范围内的所有内容。既然如此,为什么我会犯这个错误?

    1 回复  |  直到 7 年前
        1
  •  4
  •   rsjaffe    7 年前

    没有标识捕获默认值,因为捕获默认值必须是捕获中的第一项。见 cpp reference 详细情况。

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

    还有,抓捕 index 似乎没有使用。您可以消除它,在这种情况下,代码将

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

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

    :

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

    再来一个评论。虽然默认捕获在纸面上看起来很不错(一个字符,无需大惊小怪),但我喜欢使用捕获来显式地减少错误的风险,就像上面指出的那样。它还使识别lambda所依赖的变量更加容易。在这种情况下,代码变成:

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

    这只是样式上的改变——它的意思与前面的示例相同,但是在以后修改代码时应该不容易出错。