
On 1/26/07, Ovanes Markarian <om_boost@keywallet.com> wrote:
template<class T> struct LockingProxy { operator T&()const;
private: T t; };
I hadn't tried the cast operator variant; the syntax works, but...
I assume you have following type:
shared_ptr< LockingProxy<T> > ptr(new LockingProxy(params for T's ctor));
what I've actually got is shared_locking_ptr<T> ptr(new T()) where shared_locking_ptr::operator->() returns LockingProxy<T>, and shared_locking_ptr::operator*() wants to return T&. With either the cast operator you described or the more obvious LockingProxy::operator*() that I'd tried first, the LockingProxy goes out of scope (and thus unlocks) as soon as its operator completes, and before the result actually gets used. It occurs to me that there's possibly a way to do this via shared_ptr<LockingProxy<T> >, where the "ownership" of T belongs to something other than the shared_ptr or the LockingProxy; I'd originally thought that the T object would be conventionally owned by the shared_ptr and merely locked/unlocked via the proxy on access. But perhaps I'm going at this the wrong way...
Now you could at least call it:
(static_cast<T&>(*ptr)).member_of_T;
Or if you need to pass the T& to some other function without casts:
void do_smth(T const& t);
do_smth(*ptr);
This is exactly what I was trying to accomplish, with T staying locked all the way through the do_smth() call. (gory details, in case it matters: I'd originally planned on modifying boost::shared_ptr to take a second template argument (the storage policy), and then the "shared_locking_ptr" would just be a shared_ptr with a locking storage policy. Turns out that was harder than it looked at first sight.) -- Allison