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);
}
I can see in the debugger that holdFinish
is pointing to a different implementation of identifierCollection
than in the 2nd lambda function.
If I use [=, &identifierCollection]
it throws a EXC_BAD_ACCESS
whether I use mutable
or not.
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);
Would alert 15
.
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.
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.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.