Andrzej Krzemienski wrote:
But tell me this. Consider the example with class Man above:
``` struct Man { std::string fist_name, last_name; }; Man m1 = {"April", "Jones"}; Man m2 = {"Theresa", "May"};
try { m2 = m1; // suppose it throws } catch(...) { } ```
Object m2 after recovering from stack unwinding may be in the state {"April", "May"}, which is a "valid state". Would you call it a valid state?
It depends on the invariant of Man. Assuming no invariant, yes, it's valid. It doesn't crash if I access it.
Same with outcome<T>: if I assign to it and it fails:
o1 = o2; // assume basic guarantee
provided I get transactional guarantee, I know what its value is. But if I get "basic guarantee" as you describe it (valid but unspecfied state), what good does it make that I can safely call has_value() if the object contains a different value than o1 or o2 had initially?
What good it makes is that you can call has_value() on it without crashing. Without this guarantee, you could never safely call has_value() on a foreign object without checking valueless() first.