在两个Lambda之间共享变量 [英] Share variable between two lambdas
问题描述
我希望能够在两个lambda函数之间共享包含范围内的变量.我有以下内容:
I want to be able to share a variable in the containing scope between two lambda functions. I have the following:
void holdAdd(const Rect& rectangle, Hold anonymousHeld, Hold anonymousFinish) {
std::map<int,bool> identifierCollection;
HoldFinish holdFinish = [=](const int& identifier) mutable {
if (identifierCollection.count(identifier) == 0) return;
identifierCollection.erase(identifier);
anonymousFinish();
};
holdCollisionCollection.push_back([=](const int& identifier, const Vec2& point) mutable {
if (rectangle.containsPoint(point)) {
identifierCollection[identifier] = true;
anonymousHeld();
} else {
holdFinish(identifier);
}
});
holdFinishCollection.push_back(holdFinish);
}
我在调试器中看到,holdFinish
指向的identifierCollection
实现与第二个lambda函数中的实现不同.
I can see in the debugger that holdFinish
is pointing to a different implementation of identifierCollection
than in the 2nd lambda function.
如果我使用[=, &identifierCollection]
,则无论我是否使用mutable
,都会抛出EXC_BAD_ACCESS
.
If I use [=, &identifierCollection]
it throws a EXC_BAD_ACCESS
whether I use mutable
or not.
我对其他实现内联函数的语言的经验是,这应该是可能的.例如在javascript中:
My experience with other languages that implement inline functions is that this should be possible. For instance in javascript:
var a = 10;
var b = function() {
a += 2;
}
var c = function() {
a += 3;
}
b();
c();
alert(a);
会警报15
.
我该怎么做才能使两个lambda函数都引用相同的identifierCollection实现?因此它的行为与javascript示例相同.
What do I have to do to get both lambda functions to reference the same identifierCollection implementation? So that it behaves in the same way as the javascript example.
推荐答案
与某些脚本语言不同,identifierCollection
的生存期不会仅仅因为将其捕获到闭包中而延长.因此,只要将[=]
更改为要通过引用捕获的[&]
,它便是对要捕获的局部变量的悬挂引用.
Unlike in some scripting languages, identifierCollection
's lifetime won't be extended simply because you captured it into a closure. So as soon as you change that [=]
for a [&]
to capture by reference, it's a dangling reference to a local variable that you're capturing.
您必须自己管理identifierCollection
的生命周期;坦白说,这听起来像是共享指针的绝佳机会,它可以按值捕获到每个lambda中.它包装的动态分配的地图实际上会存在您需要的时间.
You'll have to manage the lifetime of identifierCollection
yourself; frankly, this sounds like the perfect opportunity for a shared pointer, captured by value into each lambda. The dynamically-allocated map it wraps will literally exist for as long as you need it to.
void holdAdd(const Rect& rectangle, Hold anonymousHeld, Hold anonymousFinish)
{
auto identifierCollection = std::make_shared<std::map<int,bool>>();
HoldFinish holdFinish = [=](const int& identifier) mutable {
if (identifierCollection->count(identifier) == 0) return;
identifierCollection->erase(identifier);
anonymousFinish();
};
holdCollisionCollection.push_back([=](const int& identifier, const Vec2& point) mutable {
if (rectangle.containsPoint(point)) {
(*identifierCollection)[identifier] = true;
anonymousHeld();
} else {
holdFinish(identifier);
}
});
holdFinishCollection.push_back(holdFinish);
}
这篇关于在两个Lambda之间共享变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!