It’s nice to make invalid states unrepresentable. Unfortunately, you can’t do that in C++ if you have a move constructor. C++ moves have to leave the source object in a valid state, since the object can still be accessed afterwards and will still have its destructor run. But unless your move is really just a copy, that state has to be some kind of default, or at least semantically meaningless. And if a valid but semantically meaningless state exists, arguably you might as well use it for the default constructor too.
I've never liked default constructors when it produces something that is not representable without executing code. D does not have default constructors. What one does is specify the statically initialized field values (or leave the fields to be set to their statically initialized value). I.e. it has a default initializer.<p>What this means in practice is one never is presented with an uninitialized or partially initialized struct. A non-default constructor gets handed a default initialized struct to start with. This makes for more reliable software. (Double initialization can be removed by the optimizer.)<p>Why D doesn't have default constructors gets brought up now and then, as it is an unusual choice.
A pattern I've seen some people do is to just make an operator bool for the type that checks for a contextually-sensical invalid state that is also the default constructed state. This is absolutely a hack, and has lots of other implications, and I wouldn't recommend it, but I see why people do it, because it creates a low-overhead way of getting around the possibility of invalid stuff while not taking on the problems of lacking a default constructor<p>Personally, I like the simplicity of this kind of approach, but prefer to force consumers of the type to be more explicit. To that end, I really like having an constexpr bool operator! instead, so the same checks can be performed without making it easy to accidentally coerce your type into some shady arithmetic operations. You still can if you meant to, but it will be more obvious what you're doing and won't happen accidentally
operator<=> was new to me. It's the three-way comparison operator.<p><a href="https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison" rel="nofollow">https://en.cppreference.com/w/cpp/language/operator_comparis...</a>