In the below contrived example I have a generic function which takes an arbitrary lambda as a callback function, checks some preconditions, and calls the lambda if they are met:
template<ApplyF>
void check_valid(CharacterId id, Operation op, ApplyF apply)
{
auto it = characters_.find(id);
if (it != characters_.end())
{
Character& character = it->second;
if (character.operation_valid(op))
{
apply(character);
}
}
}
This then allows me to reduce boilerplate and only have the lambda invoked when said preconditions are met:
void attack(CharacterId id, CharacterId enemy, double skill, double chance)
{
check_valid(id, Operation::Attack, [=](Character& character)
{
character.attack(enemy, skill, chance);
});
};
void harvest(CharacterId id, ResourceId resource, double quantity)
{
check_valid(id, Operation::Harvest, [=](Character& character)
{
character.harvest(resource, quantity);
});
};
You can see I am capturing variables required in the lambda by value.
I am also passing the lambda to check_valid
by value.
Questions:
Is dynamic memory allocation something I need to worry about?
Could the captured variables and passing the lambda by value result in dynamic memory allocations?
I know lambdas can be inlined, so in this type of usage, would the optimiser see that the capture is only a by-product of language rules, and reference the variable in the outer scope without copying anything at all?