Andrzej Krzemienski wrote:
My first reaction to this is: such a code is again fishy, ...
That may be so, but it changes not the fact that there is the basic guarantee, the standard library offers it because Dave, and then there's the destroy-only guarantee, which the standard library does not use. You are not the only person who feels that destroy-only is better, but this doesn't really matter here. (It's the same for move, by the way. There are people who prefer destroy-only for moved-from objects. The standard library does not agree with them, this time because Howard.) I realize that I'm a bit curt, so here's some explanation. Under the destroy-only guarantee, all your member functions have a precondition on valid(), assuming that you even have such an accessor (of you don't, it's even worse). Most of the time, this doesn't matter, because, as you assume, you'll never encounter invalid objects. Except when you do. So you have to split your code into two categories: functions that will never be called on invalid objects, and functions that can. You then need to make sure that first category functions are never, directly or indirectly, called during stack unwinding, either from a catch block, or from a destructor. This is possible in principle, even though it's not very reliable, because "never happen" objects, well, never happen, and therefore you often aren't testing the scenarios in which they happen. So when they do happen, it's in production. Under the basic guarantee, when your member functions don't have a "valid" precondition because objects are always valid, and when functions taking objects don't need to be split into two categories, some that can only take valid objects, and others that can take invalid ones, the world is simply a better place.