C++ relies heavily on mechanisms that help you write type-safe code. Language constructs such as explicit constructors and conversion operators have been baked into the language for a long time. More and more safe types are being introduced to the standard library. There's optional to help you avoid referencing empty values, string_view to help you avoid going out of a range, and any as a safe wrapper for any type, just to name a few. Moreover, with its zero-cost abstractions, it's recommended that you create your own types that are useful and hard or impossible to misuse.
Often, using C-style constructs can lead to type-unsafe code. One example would be C-style casts. They can resolve to a const_cast, static_cast, reinterpret_cast, or one of these two combined with a const_cast. Accidentally writing to a const object that was const_cast is undefined behavior. So is reading memory returned from a reinterpret_cast<T>,...