Ah, but there is another way. It's called boost::bind. Use it to bind the unlock functions of all the locks and wrap them in RAII objects whose destructor calls the functor it wraps. I've used this approach before.
Example:
Code:
class ScopedCallerBase
{
public:
virtual ~ScopedCallerBase() { }
}
template<typename T> class ScopedCaller: public ScopedCallerBase
{
public:
ScopedCaller(T Functor): m_Functor(Functor) { }
virtual ~ScopedCaller() { m_Functor(); }
private:
T m_Functor;
};
template<typename T> ScopedCaller<T>* CreateScopedCaller(T Functor)
{
return new ScopedCaller<T>(Functor);
}
void MyFunction(Lock& lock1, Lock& lock2, Lock& lock3)
{
std::auto_ptr<ScopedCallerBase> AutoRelLock1 = CreateScopedCaller( boost::bind(&Lock::unlock, lock1) );
std::auto_ptr<ScopedCallerBase> AutoRelLock2 = CreateScopedCaller( boost::bind(&Lock::unlock, lock2) );
std::auto_ptr<ScopedCallerBase> AutoRelLock3 = CreateScopedCaller( boost::bind(&Lock::unlock, lock3) );
}
Somewhat messy, but C++0x will make this easier. I also do believe Boost has some macros and other stuff that simplifies this.
Of course, ScopedCaller, ScopedCallerBase and CreateScopedCaller are all generic so they'll work with everything.
Of course, this is a techy C++ solution (a preferred one, I suppose) and easy to read for the trained eye.
Oh yeah, btw, welcome back, Mats.
I noticed you haven't been around for a while.