
bnv wrote:
I can't comment on whether the direction is correct, but would be in support of such a capability having recently run into the same need.
Me too.
However, I seem to recall something like this coming up before and the rationale for not supporting it is was that the behavior to follow when the weak pointer is expired is subjective. That is, in some cases you may want an exception, and in other you may want nothing to happen.
I think, it should be possible to create a policy-based solution. Something like this: weak_ptr< A > p; bind(&A::foo, throw_if_invalid(p)); bind(&A::foo, ignore_if_invalid(p)); bind(&A::foo, call_if_invalid(p, bar)); // bar is a function object This is possible if throw_if_invalid, etc. return some proxy object which has an overloaded get_pointer function and operator->* that does the job. template< typename T, typename FallbackFunT, typename FunT > class weak_ptr_caller { weak_ptr< T > const& m_p; FallbackFunT const& m_fallback; FunT m_fun; public: explicit weak_ptr_caller( weak_ptr< T > const& p, FallbackFunT const& fb, FunT f) : m_p(p), m_fallback(fb), m_fun(f) {} // here goes a bunch of operator() overloads ... operator() (args) const { if (shared_ptr< T > p = m_p.lock()) return (get_pointer(p)->*m_fun)(args); else return m_fallback(); } }; template< typename T, typename FunT > class weak_ptr_proxy { weak_ptr< T > m_p; FunT m_fun; public: explicit weak_ptr_proxy(weak_ptr< T > p, FunT f) : m_p(p), m_fun(f) {} template< typename F > weak_ptr_caller< T, Fun, F > operator->*(F f) const { return weak_ptr_caller< T, Fun, F >(m_p, m_fun, f); } }; template< typename T, typename FunT > weak_ptr_proxy< T, FunT >& get_pointer(weak_ptr_proxy< T, FunT >& p) { return p; } template< typename T, typename FunT > weak_ptr_proxy< T, FunT > call_if_invalid(weak_ptr< T > p, FunT f) { return weak_ptr_proxy< T, FunT >(p, f); }