Boost logo

Boost :

Subject: Re: [boost] [Smart Ptr][Bind] Implementaion of Weak Callback Function
From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2009-03-22 05:18:36


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);
  }


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk