Why so complicated? You don't need dynamic_cast for an upcast.
class Base {};class Derived : public Base {};void Bar(const shared_ptr<Base> &base) {}void Foo() { Bar(shared_ptr<Derived>(new Derived()));}
All that's wrong with your original example is that it's not const-correct.
If you pass a shared_ptr<Base> & (a reference to shared_ptr) to your method, that means the method can put any other object deriving from Base into the shared pointer.
This of course is incompatible with the original pointer, which only takes objects of type Derived, so if your method put an instance of OtherDerived in it, after the method returns, you would end up with a shared_ptr<Derived> that carries an OtherDerived instance.
-
Now if the non-const shared_ptr reference was intentional, you need to cast. But a temporary shared_ptr (without the dynamic cast) should solve that problem, too:
class Base {};class Derived : public Base {};void Bar(shared_ptr<Base> &base) {}void Foo() { shared_ptr<Derived> derived(new Derived()); shared_ptr<Base> base = derived; Bar(base);}