|
Boost Users : |
Subject: Re: [Boost-users] "weak" binding to member?
From: Igor R (boost.lists_at_[hidden])
Date: 2011-09-13 05:35:37
> 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);
}
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net