Earlier quoted context omitted.
It’s not just the destructor you have to worry about, it’s all of the state accessible to callers. If you have any type that represents validated data, say a string wrapper which conveys (say) a valid customer address, how do you empty it out? You could turn it into an empty string, but now that .street() method has to return an optional value, which defeats the purpose of your type representing validated data in the…
First, one shouldn't use a moved-from object in the first place (except for, maybe, reassigning it). Second, why can't the .street() method simply return an empty string in this case? > The moved-from value has to be valid after move (all of its invariants need to hold) The full quote from the C++ standard is: "Unless otherwise specified, such moved-from objects shall be placed in a valid but unspecified state" AFAIK…
It still requires you to come up with somethkng to do to the old value in the move constructor. What would you do in the ValidatedAddress case? Set a flag in the struct called “moved_from” and use that to throw an exception if it’s ever used? Wouldn’t it be nice if you just didn’t need to worry about it?
> Second, why can't the .street() method simply return an empty string in this case?
In this example I’m referring to a type that represents a “validated” address, so, one that has already passed checks to make sure the street isn’t empty, etc. (it’s the whole “parse, don’t validate” idea, although I’ve never understood why the word “parse” is used when I would’ve just called it “validate just once”.)
It is an extremely useful concept for your type system to represents invariants in your data like this. Having to make every type contain an “empty” case, just to make the language’s move semantics work, pokes an enormous hole through this idea.
> AFAIK, it only makes such requirements for standard library types, but not for user defined types
It makes the requirement because the compiler is not going to stop anyone from using the moved-from value, so you have to think of something to do in the move constructor. You can pinky-swear to never use the moved-from value in your own code (and linters can help here) but the possibility still exists, so it must be solved for.