Circumventing casts are not evidence of weakness. Those are escape hatches. Something normally not allowed by the type system is being explicitly overridden by the programmer.
Weakness consists of all that the type system doesn't catch.
Like oh, for instance: C++ local variables become pixie dust with terminates. Yet an address of these variables can escape from the scope. The type system does nothing to catch this.
Or: the pointer to a Derived can be converted to a pointer to a Base implicitly. But then pointer arithmetic can be applied. Even if there is an array of Derived there, the displacements are wrong.
Most of the unsafe features from C are present, like argument handling in variadic functions.
Explicit memory management. Code would work with an object may be perfectly well typed as far as the data representation goes except oops something already invoked the delete op on the object.
You can have code that's perfectly fine except oops when exceptions happen.
If C++ were type safe, they wouldn't be all these rules on how to write safe C++. Like do use this kind of smart pointer but don't use this other obsolete one that has issues.