6
votes

I have two shared_ptrs of the classes U and T where T is the base of U.

It is no problem to do an implicit conversion from shared_ptr<U> to shared_ptr<T>. But is is also possible to do a conversion from shared_ptr<T> to shared_ptr<U> ?

I tried the sugested solution:

class T {
public:
  virtual ~T() {}
protected: 
  void fillData() = 0;
};

class Timpl : public T 
{ 
public:
  virtual ~Timpl() {}
protected:
  virtual void fillData() = 0;
};

class U : public Timpl {
public: 
  virtual ~U() {}
protected: 
  virtual void fillData() {...} // fill 
};

typedef  shared_ptr<T> TPtr
typedef  shared_ptr<U> UPtr


TPtr tp = std::make_shared<U>();  
UPtr up = std::static_pointer_cast<U>(tp);    //<-- error here :

error: no matching function for call to 'static_pointer_cast(TPtr)'

note: template std::__shared_ptr<_Tp1, _Lp> std::static_pointer_cast(const std::__shared_ptr<_Tp2, _Lp>&)

note: template argument deduction/substitution failed:

note: 'TPtr {aka boost::shared_ptr}' is not derived from 'const std::__shared_ptr<_Tp2, _Lp>'

Solution for this issue:

mixing of std::shared_ptr with boost::shared_ptr is no good idea.

1

1 Answers

11
votes

Yes, use static_pointer_cast:

#include <memory>

struct T { virtual ~T() {} };
struct U : T {};

std::shared_ptr<T> pt = std::make_shared<U>();     // *pt is really a "U"

auto pu = std::static_pointer_cast<U>(pt);

There's also a matching std::dynamic_pointer_cast which returns a null pointer if the conversion isn't possible.