On Thu, Nov 20, 2014 at 4:29 AM, Andrzej Krzemienski
2014-11-19 22:36 GMT+01:00 Vladimir Batov
: On 11/20/2014 08:22 AM, Vladimir Batov wrote:
On 11/19/2014 07:37 PM, Andrzej Krzemienski wrote:
...
optional<double> Aircraft::weight() { if (Impl* impl = get_impl()) return impl->compute_weight(); else return none; }
double Aircraft::max_weight() { return 10000.0; }
bool too_heavy(Aircraft& ac) { return ac.weight() > ac.max_weight(); // in "safe" optional compiler would spot the bug }
There is no bug here! Not from the human perspectives. You are comparing two extremely closely related types! As long as we agree on how "none" is treated, then all kosher. We do compare "ints" with "doubles", don't we? No "safety" concerns.
On the second thought I might probably agree that op<() might be questionable... Can we address that differently then?
No. Allowing this comparison to work is the right thing to do. It is a natural consequence of Optional's conceptual model. You should look at optional<T> as a T plus one additional value, less than any other value. No-one stops you from adopting any other model (like container of size 0-or-1), but then you are risking that you will be surprised by the result.
The "correct" model is actually initialized-or-not. For non-Regular types (&T or others), anything else is surprising. In particular, the nature of optional assignment is construct-or-assign. For Regular types, there is no real difference, for custom types there might be. Its behaviour of assignment is, to me, the fundamental essence of optional. Seeing it as may-be-uninitialized would suggest that less-than-comparison doesn't make much sense. (Equality still makes sense, IMO) Tony