title: C++20 behaviour breaking existing code with equality operator?
body: <p>I ran into this while debugging <a href="https://stackoverflow.com/questions/65638680/using-boost-strong-typedef-to-differentiate-arg-types-but-causing-seg-fault/65643014?noredirect=1#comment116069484_65643014">this question</a>.</p>
  <p>I trimmed it down all the way to just using <a href="https://www.boost.org/doc/libs/1_75_0/libs/utility/operators.htm" rel="noreferrer">Boost Operators</a>:</p>
  <ol>
  <li><p><strong>Compiler Explorer <a href="https://godbolt.org/z/q89brM" rel="noreferrer">C++17</a> <a href="https://godbolt.org/z/szYx9E" rel="noreferrer">C++20</a></strong></p>
  <pre><code>#include &lt;boost/operators.hpp&gt;
  
  struct F : boost::totally_ordered1&lt;F, boost::totally_ordered2&lt;F, int&gt;&gt; {
      /*implicit*/ F(int t_) : t(t_) {}
      bool operator==(F const&amp; o) const { return t == o.t; }
      bool operator&lt; (F const&amp; o) const { return t &lt;  o.t; }
    private: int t;
  };
  
  int main() {
      #pragma GCC diagnostic ignored &quot;-Wunused&quot;
      F { 42 } == F{ 42 }; // OKAY
      42 == F{42};         // C++17 OK, C++20 infinite recursion
      F { 42 } == 42;      // C++17 OK, C++20 infinite recursion
  }
  </code></pre>
  <p>This program compiles and runs fine with C++17 (ubsan/asan enabled) in both GCC and Clang.</p>
  </li>
  <li><p>When you change the <em>implicit</em> constructor to <code>explicit</code>, the problematic lines obviously <strong><a href="https://godbolt.org/z/hq4fve" rel="noreferrer">no longer compile on C++17</a></strong></p>
  </li>
  </ol>
  <p>Surprisingly both versions <strong>compile on C++20 (<a href="https://godbolt.org/z/onMzo5" rel="noreferrer">v1</a> and <a href="https://godbolt.org/z/b1Pav5" rel="noreferrer">v2</a>)</strong>, but they lead to <strong>infinite recursion</strong> (crash or tight loop, depending on optimization level) on the two lines that wouldn't compile on C++17.</p>
  <p>Obviously this kind of silent bug creeping in by upgrading to C++20 is worrisome.</p>
  <p>Questions:</p>
  <ul>
  <li>Is this c++20 behaviour conformant (I expect so)</li>
  <li>What exactly is interfering? I suspect it might be due to c++20's new &quot;spaceship operator&quot; support, but don't understand <strong>how</strong> it changes the behaviour of this code.</li>
  </ul>