Boost logo

Boost :

From: Valentin Bonnard (Bonnard.V_at_[hidden])
Date: 2000-01-18 11:21:58


First, happy new year everyone !

Braden N. McDaniel wrote:

> Is there any way to downcast a shared_ptr? That is, the effect of
>
> shared_ptr<Base> base(new Base);
> shared_ptr<Derived> derived(base);

I don't want to be able to write that w/o causing the
compiler to complain !

Sadly, new style casts can't be overloaded.

When similar functionnality was desired, Matt Austern
proposed in London the use of do_static_cast,
do_const_ etc for generalised allocator::pointer.
I tend to like that.

I propose (untested code):

#define DEFINE_PSEUDO_CAST(THE_CAST) \
template <typename To, typename From> \
shared_ptr<To> do_ ## THE_CAST ## _cast (const shared_ptr<From>& p) \
{ \
    ++*p.pn; \
    return shared_ptr<To> (THE_CAST ## _cast<To*> (p.px), p.pn); \
}

DEFINE_PSEUDO_CAST(const)
DEFINE_PSEUDO_CAST(static)

template <typename To, typename From>
shared_ptr<To> do_dynamic_cast (const shared_ptr<From>& p)
{
    if (To* pto = dynamic_cast<To*> (p.px))
    {
        ++*p.pn;
        return shared_ptr<To> (pto, p.pn);
    }
    else
        return shared_ptr<To> ();
}

With

friend template <typename To, typename From>
shared_ptr<To> do_dynamic_cast (const shared_ptr<From>& p);
friend template <typename To, typename From>
shared_ptr<To> do_const_cast (const shared_ptr<From>& p);
friend template <typename To, typename From>
shared_ptr<To> do_static_cast (const shared_ptr<From>& p);

With the appropriate two args ctor:

private:
  shared_ptr(T* px_, long* pn_)
    : px(px_), pn(pn_) {}

(In the long term (next standard revision) someone might
propose the overloading of casts in C++, just like other
operators.)

-- 
Valentin Bonnard

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk