While chasing a bug in a program I found out that equality comparison operator T vs optional<T> is broken if T is optional<U>. It is broken in worst possible way - it compiles but for some values it returns wrong results!
Here is an example:
https://godbolt.org/z/v3bcTodGj
Since both sides of eq operator are specialization of optional then following overload is used:
operator==(const optional<T>& lhs, const optional<U>& rhs);This operator is specified to return
lhs.has_value() != rhs.has_value() ? false : (lhs.has_value() == false ? true : *lhs == *rhs) This falls apart for above scenario since lhs has value while rhs no value.
Since this is a case of optional<T>{} == T{} comparison, such scenario should be handled separately. Here is my attempt at fixing it:
https://godbolt.org/z/Yq3nM4xn4
This is rather not a proper fix, since it will still break for cases like
optional<optional<short>>{} == optional<int>{}, and the internal if-constexpr instead should probably compare the nestedness of lhs and rhs optional.I didn't check but most likely the same problem applies to relational operators.
https://redd.it/1tafsep
@r_cpp