我通过引用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;
}
});
答案 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
})