https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96269
--- Comment #2 from sshannin at gmail dot com --- (In reply to Jonathan Wakely from comment #1) > Your operator== should be const-qualified. I don't disagree. I can also fully remove the operator== and it compiles as well (why should the presence of the non-const operator== cause the comparison with nullopt in one direction to instantiate it). But yeah, I lost something in my reduction in there. I think the main point is that one direction of the comparison instantiates the templated operator== and the other doesn't. Consider this version of X instead, which avoids the const issues: struct X { int y; template <typename T> bool operator==(const T&o) const { return y == o.summary(); } }; We again end up instantiating X's operator== (even though we wouldn't call it) in the FLIP case (and thus fail to compile), but in the non-flip case everything seems fine.