Boost logo

Boost :

Subject: Re: [boost] Help with shared_ptr usage?
From: Sumant Tambe (sutambe_at_[hidden])
Date: 2011-06-03 18:04:55


Hi Johnny,

Sound like the type coercion you are trying to achieve can be done using
templatized constructor and a templatized copy assignment operator.
I would first start with the Coercion by member template idiom here:
http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Coercion_by_Member_Template
Looks like you using C++0x. So you may also want to throw in a static_assert
that checks the inheritance relationship between type parameters using
boost::is_base_of<T1,
T2>

Code below tested on g++4.6 seems to work on your program.

template<class T>
class BaseRef_T {
    template <class U>
    BaseRef_T (const BaseRef_T<U> & baseu): impl_(baseu.impl_) {
      static_assert(std::is_base_of<T, U>::value, "T is not base of U");
    }
    template <class U>
    BaseRef_T & operator = (const BaseRef_T<U> & baseu) {
      static_assert(std::is_base_of<T, U>::value, "T is not base of U");
      this->impl_=baseu.impl_;
      return *this;
    }
};

Finally, you may want to ask questions like these on stackoverflow where
responses are quicker and the right answer gets upvotes overtime increasing
confidence in it.

Sumant

On 3 June 2011 01:20, Johnny Willemsen <jwillemsen_at_[hidden]> wrote:

> Hi,
>
> I can need some help with getting similar behavior as with shared_ptr
> for my classes., I have used std::shared_ptr with C++0x which matches
> the boost support.
>
> I have two classes, Base and Derived. Now I want to give our users not
> directly access to these implementation classes, but to some reference
> to them. I have created two templates, BaseRef_T and Derived_objref (see
> below). In Derived_objref I need to add some additional typedefs and
> type definitions. I have tried first to add these typedefs to a
> specialization of shared_ptr<> but couldn't get a clean solution.
>
> If I now use shared_ptr I can take a shared_ptr for a Derived and assign
> it to a BaseRef_T. That works without problems. But how to accomplish
> this with my own wrapper classes. This should only be possible when the
> types are related to inheritance. If I have now a D that is not derived
> from Base than that shouldn't work.
>
> Johnny
>
> #include <memory>
>
> class Base
> {
> public:
> };
>
> class Derived : public virtual Base
> {
> public:
> };
>
> template <typename T>
> class BaseRef_T
> {
> public:
> BaseRef_T (std::shared_ptr <T> t) : impl_ (t) {};
> BaseRef_T (T* t) : impl_ (t) {};
> BaseRef_T (void) : impl_ () {};
> typedef T element_type;
> inline T* operator-> () { return impl_.get ();}
> inline T* get() const { return impl_.get ();}
> explicit operator bool() const // never throws
> { return impl_ == 0 ? false : true; }
> void
> operator=(const std::nullptr_t& t) // never throws
> {
> impl_ = t;
> }
>
> // protected:
> typedef std::shared_ptr <T> shared_ptr_type;
> shared_ptr_type impl_;
> };
> typedef BaseRef_T <Base> BaseRef;
>
>
> template <typename T>
> class Derived_objref
> : public virtual BaseRef_T <T>
> {
> public:
> Derived_objref () : BaseRef_T<T> () {}
> Derived_objref (T *s) : BaseRef_T<T> (s) {}
> Derived_objref (const BaseRef_T <T>& o) : BaseRef_T <T> (o) {}
> void operator=(const std::nullptr_t& t) { this->impl_ = t; }
> typedef int my_index_type; // Needed as additional typedef for Derived
> struct Foo {int a;};
> };
> typedef Derived_objref <Derived> DerivedRef;
>
> int main (int,char*[])
> {
> std::shared_ptr<Base> bs (new Base);
> std::shared_ptr<Derived> ds (new Derived);
> std::shared_ptr<Base> cs = ds;
> BaseRef b (new Base);
> DerivedRef d(new Derived);
> BaseRef c = d; // <== how to get this working?
> return 0;
> }
>
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>

-- 
int main(void)
{
     while(1) KeepWorking();
}

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