c ++捕获了对bool错误值的引用

时间:2014-07-31 13:34:42

标签: c++ c++11 lambda boolean

我通过引用lambda来捕获本地bool值,并且第一次捕获它时,值是未分配的(某个随机值)。为什么呢?

bool singleConfirmed=false;
        button->addTouchEventListener([text, &singleConfirmed](Ref*, Widget::TouchEventType type)
        {
            if (type != Widget::TouchEventType::ENDED) return;
            if (!singleConfirmed)
            {
                cocostudio::ActionManagerEx::getInstance()->playActionByName(R_tutorialDialog.c_str(), "MoveToTop");
                text->setString(G_str("Tutorial_Single/Multiplayer"));
                singleConfirmed=true;
                return;
            }
            else
            {
                cocostudio::ActionManagerEx::getInstance()->playActionByName(R_tutorialDialog.c_str(), "SwipeToLeft");
                text->setString(G_str("Tutorial_Single/Multiplayer"));
                return;
            }
        });

2 个答案:

答案 0 :(得分:2)

提供的代码中没有足够的上下文可以肯定,但正如评论中暗示的那样,问题几乎肯定是singleConfirmed是一个超出范围的自动局部变量(已被破坏) )当lambda被调用时,这意味着lambda将使用野生引用。要解决此问题,您需要使用在范围退出时不会被销毁的内容。这意味着动态分配。动态分配意味着您需要在lambda被销毁时解除分配。确保这一点的最简单方法是使用智能指针。综上所述,我的建议是将bool存储在shared_ptr中并按值捕获:

auto singleConfirmed = std::make_shared<bool>(false);
button->addTouchEventListener([text, singleConfirmed](Ref*, Widget::TouchEventType type)
{
   // ...
}

text似乎是某种你通过值捕获的指针,所以只要在lambda消失之前它没有得到delete d就应该没问题了< / p>

答案 1 :(得分:0)

正如斯沃特和dlf的评论所暗示的那样,lambda几乎肯定会超出局部变量singleConfirmed的范围。 addTouchEventListener的名称强烈建议稍后将存储和执行函数对象以响应某些用户事件,而不是现在同步执行。

当lambda将在创建它的作用域之外执行时,通过引用捕获变量是没有意义的,因为这些变量在#&#的时候将超出范围39; s执行,因此,使用该引用无效。

相反,您应该按值捕获。但是,默认情况下,值捕获变量为const,因此您无法在lambda中分配它,因为您似乎想在此处执行此操作。您需要声明lambda mutable以使值捕获变量为非const

bool singleConfirmed = false;
button->addTouchEventListener(
    [text, singleConfirmed](Ref*, Widget::TouchEventType type) mutable {
        // everything in here stays the same
    })