In the classic problem of transferring money from one bank account to another, the accepted solution (I believe) is to associate a mutex with each bank account, then lock both b
I think your answer is to do as you suggest and use std::lock(), but put it into a friend function. That way you don't need to make the account mutex public. The deposit() and withdraw() functions are not used by the new friend function and will need to separately lock and unlock the mutex. Remember that friend functions are not member functions but do have access to private members.
typedef int Money;
class Account {
public:
Account(Money amount) : balance(amount)
{
}
void deposit(const Money& amount);
bool withdraw(const Money& amount);
friend bool transfer(Account& src, Account& dest, const Money& amount)
{
std::unique_lock src_lock(src.m, std::defer_lock);
std::unique_lock dest_lock(dest.m, std::defer_lock);
std::lock(src_lock, dest_lock);
if(src.balance >= amount)
{
src.balance -= amount;
dest.balance += amount;
return true;
}
return false;
}
private:
std::mutex m;
Money balance;
};