https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96269
--- Comment #6 from sshannin at gmail dot com --- Thanks to you both for your analysis. As I said, I wasn't sure if it was an issue, so I'm certainly willing to accept that it's not. The one point I wanted to emphasize though just to make sure we're talking about the same thing is that it seems to odd to me that we're instantiating any form of comparison function for type T. We're comparing optional<T> to nullopt_t, so it would seem that it shouldn't matter whether T itself is even comparable. More specifically, header <optional> defines operator<=>(const optional<T> &x, nullopt_t), with the very simple body of bool(x) <=> false, as expected (circa line 1050, gated by #ifdef __cpp_lib_three_way_comparsion). This is why the non-flip case works, it hits the spaceship overload for (optional, null_opt_t). But there is no such operator in the other direction: (null_opt_t, optional). So we end up hitting optional's plain templated operator==() at ~line 1120, which of course ultimately instantiates the T's (broken/weird) operator. I guess to rephrase, should there also be a specialized spaceship overload for the (nullopt_t, optional) direction to complement the (optional, nullopt) one?