See here:
dynamic_cast can only be used with pointers and references to classes (or with void*). Its purpose is to ensure that the result of the type conversion points to a valid complete object of the destination pointer type.
This naturally includes pointer upcast (converting from pointer-to-derived to pointer-to-base), in the same way as allowed as an implicit conversion.
But dynamic_cast can also downcast (convert from pointer-to-base to pointer-to-derived) polymorphic classes (those with virtual members) if -and only if- the pointed object is a valid complete object of the target type.
Why dynamic_cast is ok to use for upcast for non polymorphic types but is not OK for downcast again for non-polymorphic types?
null_ptr
if it is not. Otherwise[expr.dynamic.cast]
says it has to be polymorphic for down casts. – NathanOliver