To do this cast you need to get the actual stored pointer in base[0]
like this:
static_cast<Derived*>(bases[0].get())->print()
EDIT:
I agree with @Tietbohl in that dynamic_cast
is safer, and that downcasting can be an indicator of bad design. However there are a few situations where, downcasting makes sense, and you can be certain that it is safe.
For example, let's say that you have a factory method, that creates an object with a certain interface, but you provide a parameter indicating that you want a specific concrete class, and then you need to perform operations on the returned object:
Interface* object = factory->CreateObject([parameter specifies type ConcreteA]);
...
static_cast<ConcreteA*>(object)->FuncOnA();
In this situation, you can avoid the complications of RTTI by simply using static_cast
.