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
#include
#include <utility>
template
class invoker
{
public:
typedef std::pair 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
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 operator->*(R (T::*pmf)()) const
{
return std::make_pair(p_, pmf);
}
template
const invoker operator->*(R (T::*pmf)(Arg1)) const
{
return std::make_pair(p_, pmf);
}
template
const invoker
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);
}