Boost logo

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