title: Overloaded operator ambiguity on Clang but not on GCC, which one is correct?
body: <pre><code>#include &lt;iostream&gt;
  
  
  template &lt;typename T&gt;
  struct Wrapper {
      operator T const &amp;() const &amp; {
          std::cout &lt;&lt; "Wrapper::operator T const &amp;() const &amp;\n";
          return _obj;
      }
  
      operator T&amp;() &amp; {
          std::cout &lt;&lt; "Wrapper::operator T&amp;() &amp;\n";
          return _obj;
      }
  
      operator T&amp;&amp;() &amp;&amp; {
          std::cout &lt;&lt; "Wrapper::operator T&amp;&amp;() &amp;&amp;\n";
          return std::move(_obj);
      }
  
  private:
      T _obj;
  };
  
  struct Test {
      Test&amp; operator=(Test const &amp;test) {
          std::cout &lt;&lt; "Test&amp; Test::operator=(Test const &amp;)\n";
          return *this;
      }
  
      Test&amp; operator=(Test &amp;&amp;test) {
          std::cout &lt;&lt; "Test&amp; Test::operator=(Test &amp;&amp;)\n";
          return *this;
      }
  };
  
  int main() {
      Test test;
      Wrapper&lt;Test&gt; wrapperTest;
  
      test = wrapperTest;               // OK for all
      test = std::move(wrapperTest);    // OK for GCC and ICC, not for Clang and VC++
  
      return 0;
  }
  </code></pre>
  
  <p>VC++ :</p>
  
  <blockquote>
    <p>(34): error C2593: 'operator =' is ambiguous</p>
    
    <p> (26): note: could be 'Test &amp;Test::operator =(Test &amp;&amp;)'</p>
    
    <p> (25): note: or       'Test &amp;Test::operator =(const Test &amp;)'</p>
    
    <p> (69): note: while trying to match the argument list '(Test, Wrapper)'</p>
    
    <p>========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========</p>
  </blockquote>
  
  <p>Clang :</p>
  
  <blockquote>
    <p>:34:7: error: use of overloaded operator '=' is ambiguous (with operand types 'Test' and 'typename std::remove_reference &amp;>::type' (aka 'Wrapper'))</p>
    
    <p>test = std::move(wrapperTest);          // OK for GCC and ICC, not for Clang and Microsoft Visual C++</p>
    
    <p>~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~</p>
    
    <p>:25:8: note: candidate function</p>
    
    <p>Test&amp; operator=(Test const &amp;test) { std::cout &lt;&lt; "Test&amp; Test::operator=(Test const &amp;)\n"; return *this; }</p>
    
    <p>^</p>
    
    <p>:26:8: note: candidate function</p>
    
    <p>Test&amp; operator=(Test &amp;&amp;test) { std::cout &lt;&lt; "Test&amp; Test::operator=(Test &amp;&amp;)\n"; return *this; }</p>
    
    <p>^</p>
    
    <p>1 error generated.</p>
  </blockquote>