I have the following pattern:
struct Wrapper
{
vector<shared_ptr<BaseType>> data;
template <typename DerivedType>
add(const DerivedType& e)
{
data.push_back(make_shared<DerivedType>(e));
};
}
The goal of my Wrapper
is to use polymorphism, I want to be able to cast back any e
to its DerivedType
.
Now, if I have B
, a derived class of A
, and I do this:
wrapper.add(B());
The type inference could resolve DerivedType
as B
.
DerivedType
as A
as well since B()
has base type A
even if it's not its most derived type?make_shared<A>(e)
produce a shared pointer that can be dynamically casted into shared_ptr<B>
?Could template inference resolve
DerivedType
asA
as well sinceB()
has base typeA
even if it's not its most derived type?
No. You would have to pass in an actual A
variable to make DerivedType
deduce as A
, or else set DerivedType
to A
explicitly.
If yes, does
make_shared<A>(e)
produce a shared pointer that can be dynamically casted intoshared_ptr<B>
?
No. make_shared()
creates exactly what you ask it to create. In this case, it would create a new A
object, which is copy-constructed by slicing e
into an A
. As there would be no B
present in the new A
object, you cannot cast it later to a B
.
To make that work correctly, you would have to use make_shared<B>()
to create a B
object, and then assign the result to a shared_ptr<A>
, which can then be later casted back to shared_ptr<B>
via std::dynamic_pointer_cast
.