title: Inherited synthesized comparison operator produces warning/error: ISO C++20 considers use of overloaded operator '!='
body: <p>In the following code snippet clang 11.0.1 generates a warning</p>
  <pre class="lang-cpp prettyprint-override"><code>template &lt;class T&gt;
  struct iterator_facade
  {
      template&lt;class S&gt;
      bool operator==(const S &amp;other) const noexcept
      {
          return static_cast&lt;const T &amp;&gt;(*this).equal_to(other);
      }
  };
  
  struct iterator : public iterator_facade&lt;iterator&gt;
  {
      bool equal_to(const iterator &amp;) const noexcept
      {
          return true;
      }
  };
  
  bool check(iterator a, iterator b)
  {
      return a == b;
  }
  
  </code></pre>
  <p>The code live:
  <a href="https://godbolt.org/z/65zWEq" rel="nofollow noreferrer">https://godbolt.org/z/65zWEq</a></p>
  <pre><code>source&gt;:21:14: warning: ISO C++20 considers use of overloaded operator '==' (with operand types 'iterator' and 'iterator') to be ambiguous despite there being a unique best viable function [-Wambiguous-reversed-operator]
      return a == b;
             ~ ^  ~
  &lt;source&gt;:5:7: note: ambiguity is between a regular call to this operator and a call with the argument order reversed
          bool operator==(const S &amp;other) const noexcept
               ^
  </code></pre>
  <p>The code above compiles successfully with Visual C++ (VS 16.8.x) and with previous preview (VS 16.9.0 Preview 2). However, recently released VS 16.9.0 Preview 3 now produces error for this code snippet:</p>
  <pre><code>1&gt;C:\MyProjects\test\test\source.cpp(21,16): error C2666: 'foo&lt;bar&gt;::operator ==': 2 overloads have similar conversions
  1&gt;C:\MyProjects\test\test\source.cpp(5,7): message : could be 'bool iterator_facade&lt;iterator&gt;::operator ==&lt;bar&gt;(const S &amp;) noexcept const' [rewritten expression '!(x == y)']
  1&gt;        with
  1&gt;        [
  1&gt;            S=iterator
  1&gt;        ]
  1&gt;C:\MyProjects\test\test\source.cpp(5,7): message : or 'bool iterator_facade&lt;iterator&gt;::operator ==&lt;iterator&gt;(const S &amp;) noexcept const' [synthesized expression '!(y == x)']
  1&gt;        with
  1&gt;        [
  1&gt;            S=iterator
  1&gt;        ]
  1&gt;C:\MyProjects\test\test\source.cpp(21,16): message : while trying to match the argument list '(iterator, iterator)'
  </code></pre>
  <p>Does it look like there is no compliant way to provide synthesized comparison operators for a derived class <code>iterator</code> with CRTP class <code>iterator_facade</code>?</p>