
I know that 'bind' (now in std::tr1) will bind pointers to member functions to smart pointers. But is there a simple way to bind to a "weak" pointer, such that the attempted call will realize the smart pointer and if successful perform the call, or if unsuccessful just not call anything without complaint? (In this case, it appears that the return is void)
Well, I think I've figured out how to solve your problem. Since Boost.Bind invokes your functor through ->* operator, you just need to define your own get_pointer() function that returns an adapter that defines ->* operator, which would do what you want. The last step is somewhat cumbersome, but you can use the following Meyers' article: http://www.aristeia.com/Papers/DDJ_Oct_1999.pdf I've tested the following code and it seems to work: #include <boost/bind.hpp> #include <boost/smart_ptr.hpp> #include <utility> template <typename C, typename R, typename F> class invoker { public: typedef std::pair<C*, F> call_info; invoker(const call_info& info) : ci_(info) {} R operator()() const { return ci_.first ? (ci_.first->*ci_.second)() : R(); } template <typename Arg1> R operator()(Arg1 p1) const { return ci_.first ? (ci_.first->*ci_.second)(p1) : R(); } template <typename Arg1, typename Arg2> R operator()(Arg1 p1, Arg2 p2) const { return ci_.first ? (ci_.first->*ci_.second)(p1, p2) : R(); } private: call_info ci_; }; template <typename T> class ptr_adapter { public: ptr_adapter(T *p): p_(p) {} template <typename R> const invoker<T, R, R (T::*)()> operator->*(R (T::*pmf)()) const { return std::make_pair(p_, pmf); } template <typename R, typename Arg1> const invoker<T, R, R (T::*)(Arg1)> operator->*(R (T::*pmf)(Arg1)) const { return std::make_pair(p_, pmf); } template <typename R, typename Arg1, typename Arg2> const invoker<T, R, R (T::*)(Arg1, Arg2)> operator->*(R(T::*pmf)(Arg1, Arg2)) const { return std::make_pair(p_, pmf); } private: T *p_; }; namespace boost { template<class T> ptr_adapter<T> get_pointer(const boost::weak_ptr<T> &p) { return ptr_adapter<T>(p.lock().get()); } } struct test { int func(int i, int j) { return i + j; } }; int main() { boost::shared_ptr<test> p(new test); boost::weak_ptr<test> w = p; auto func = boost::bind(&test::func, w, _1, _2); int res = func(1, 2); p.reset(); res = func(1, 2); }