|
Boost : |
From: Paul Mensonides (pmenso57_at_[hidden])
Date: 2002-07-08 16:39:05
> Now,
>
> (p->*fighters)();
>
> does not compile, but
>
> (p.get()->*fighters)();
>
> does. Is this by design, or possibly an oversight? The .get() form
> works, but it would be nicer if shared_ptr handled the "native" form
> automagically (yes, this is from real code...I'm not asking for
> superfluous reasons...of course, the names have been changed to
> protect the innocent).
>
> Dave
It is possible to implement a closure facility to handle this. The preprocessor
library can generate the necessary specializations to support various
pointer-to-member arities.
Off the top of my head:
template<class> class closure;
// pointers-to-data-members
template<class O, class T>
class closure<T O::*>
{
public:
typedef T& return_type;
static inline T& make(O* obj, T O::* ptr)
{
return obj->*ptr;
}
};
// pointers-to-member-functions
template<class R, class O>
struct closure<R (O::*)(void)>
{
private:
O* m_obj;
typedef R (O::* ptm_t)(void);
ptm_t m_ptr;
public:
typedef closure return_type;
inline closure(O* obj, ptm_t ptr)
: m_obj(obj), m_ptr(ptr)
{
return;
}
inline R operator()(void) const
{
return (m_obj->*m_ptr)();
}
static inline closure make(O* obj, ptm_t ptr)
{
return closure(obj, ptr);
}
};
// repeat above with various arities and cv-qualifiers
template<class T, class U>
inline typename closure<U>::return_type
make_closure(T* obj, U ptr)
{
return closure<U>::make(obj, ptr);
}
// at this point, operator->* is implementable like this:
template<class T> class smart_ptr {
private:
T* m_obj;
public:
// ...
template<class U>
inline typename closure<U>::return_type
operator->*(U ptr)
{
return make_closure(m_obj, ptr);
}
// ...
};
I'm sure other boosters can do better than this by fiddling with type traits,
etc.. This is just an example of how it *can* be done.
Paul Mensonides
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk