▲ | sgsjchs 3 days ago | |||||||
> No, the class can use a sentinel value internally only to mark moved-from objects. That's exactly where we actually started the conversation. The issue is that the "moved-from" state is exposed to the user when the moves are not destructive. The author of the class has to consider behavior for every method in sentinel state, even when it's just to assert that the state isn't sentinel or "lol it's UB". And the user has to be careful not to accidentally misuse an object in sentinel state. Just like how every time you touch a nullable pointer you have to consider if it can be null and what to do in that case. As long as the sentinel state is exposed at all (via non-destructive move), there is little gain in not providing full support for it. However, with destructive moves the sentinel value either doesn't exist at all or only exists completely internally as an optimization, and all this mental overhead disappears. | ||||||||
▲ | spacechild1 3 days ago | parent [-] | |||||||
I see your point. Just a few things: 1. This is only relevant when using such class as a local variable. Member variables are typically not moved-from. 2. In my understanding the user has the freedom to specify what constitutes a "valid but unspecified state" and it would be perfectly ok to mandate that anything you can do with a moved-from object is to either destroy or reassign it. 3. The problems with the state of moved-from objects from the perspective of a library author could have been prevented simply by imposing stricter requirements in the standard (e.g. every usage except destruction, and possible reassignment, shall be UB). 4. With all the issues you've pointed out, it is still be perfectly possible and reasonable to design a socket class your way (= no closed socket state) in C++, yet somehow most people seem to prefer open() and close() methods instead of modelling the state with an optional. Even in the presence of destructive moves, I don't think that one way is necessarily better than the other and it is mostly a matter of culture and personal preference. All the being said, I definitely agree that destructive moves are good thing, in particular if the compiler prevents you accidentally accessing moved-from objects (which is a mistake that is very easy to make in C++). | ||||||||
|