$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
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