I have an STL container and I need to perform an action on each element in the container. But if the action fails on any element, I want to reverse the action on any elements that have already been changed.
For example, if I had an STL vector with pointers to a number bankAccount classes and wanted to increase each one by $50. But if any of the bank accounts fail to increase by 50, I want to cancel the increase entirely and decrease by $50 any of the accounts that have already been increased.
std::vector<bankAccount*> bankAccounts;
std::vector<bankAccount*>::iterator iter;
for (iter = bankAccounts.begin(); iter != bankAccounts.end(); ++iter)
{
try
{
iter->increaseBalance(50);
}
catch (...)
{
// One of the bankAccounts failed to increase by 50, now I need to go
// back and decrease by 50 all of the bankAccounts that have already
// been increased.
}
}
Is there any elegant way to do this? Maybe with STL algorithms or using reverse iterators?
Here’s what I would do:
bankAccountscontainerincreaseBalanceon each itemswap()the original and the duplicate containerThe code would look something like this:
Please note that holding a pointer to an object inside a
std::vectoris generally not that good an idea as the container expects the data stored in it to have value semantics, not pointer semantics. This can lead to dangling pointers, memory leaks and also requires additional cleanup code that you don’t need otherwise (to delete the items in container manually). With the code above, I’ve switched to holding the data inside the vector, if that’s not an option you need to ensure that you’re using a manual deep copy when you’re copying the vector.Actually, you can reduce the code to the following if you assume the same definitions for
bankAccountsandtmp:The main advantage of the code above is that in both cases, it is exception safe without any further special handling.