On 21/11/2014 09:57, Vladimir Batov wrote:
3. What I have doubts about (and I stress -- doubts -- as indicated by my previous conflicting posts) is op<(T, optional<T>). Yes, *mechanically*, one can say -- T is implicitly propagated to optional<T> and then op<(optional<T>, optional<T>) is applied. Easy-peasy. I wish life was that straightforward.
*It feels to me* that, when T is compared to optional<T>, it is quite likely a bug -- it's far too open for misuse and (mis)interpretation. Based on that feeling I tend to suggest banning op<(T, optional<T>). With that we "kill two birds" -- (a) we address the safety concern you raised and (b) we achieve that within the "optional" framework without losing any existing functionality.
+1. Implicit T -> optional<T> conversion is good and essential. operator==(optional<T>, optional<T>) and operator<(optional<T>, optional<T>) are both good and essential. operator==(T, optional<T>) and operator==(optional<T>, T) are also good and convenient (but not essential). operator<(T, optional<T>) and operator<(optional<T>, T) are more dubious; it is probably better to require explicit conversion here, even though *technically* they should be implicit given the above. While granted the current definitions of this fit the model that "none" is just an extra value that is less than any other value, I feel like this case has more potential for error, especially for those people using optional<T> to represent an undefined value (though as you said, perhaps there should be a separate type for that concept -- though I've never liked any type that tries to claim none != none). Having said that, apart from a few initial surprises with optional<bool> that I quickly learned the quirks of (and it was less surprising than tribool, at that), I've never had any personal problems with the current interface of optional<T>.