One of the core problems is C++’s design basically requires it: there’s no other way to error from a ctor, and since ctors are used as hooks in many operations the dishonest rejoinder of “just use a factory” doesn’t work in any capacity.
Anyway, Rust basically deals with it by giving the class designer the choice to supply factory functions or punt on it, making the user initialize every field themselves each time. And I think most agree that this is a good approach; it's the best of C++ (factories) with a better fallback than a default constructor.
I think the naming is also important for cases where there are potentially multiple reasonable defaults, even something as basic as the difference between Vector3::Vector3() and Vector3::zero().
In C++ the constructor without arguments is called default constructor. Of course the expectations depend on conventions, but usually it's something from uninitialized garbage to an empty state.