title: Move Assignment incompatible with Standard Copy and Swap
body: <p>Testing out the new Move Semantics.</p>
  
  <p>I just asked about an issues I was having with the Move Constructor. But as it turns out in the comments the problem is really that the "Move Assignment" operator and  "Standard Assignment" operator clash when you use the standard "Copy and Swap" idiom.</p>
  
  <p>This is the class I am using:</p>
  
  <pre><code>#include &lt;string.h&gt;
  #include &lt;utility&gt;
  
  class String
  {
      int         len;
      char*       data;
  
      public:
          // Default constructor
          // In Terms of C-String constructor
          String()
              : String("")
          {}
  
          // Normal constructor that takes a C-String
          String(char const* cString)
              : len(strlen(cString))
              , data(new char[len+1]()) // Allocate and zero memory
          {
              memcpy(data, cString, len);
          }
  
          // Standard Rule of three
          String(String const&amp; cpy)
              : len(cpy.len)
              , data(new char[len+1]())
          {
              memcpy(data, cpy.data, len);
          }
          String&amp; operator=(String rhs)
          {
              rhs.swap(*this);
              return *this;
          }
          ~String()
          {
              delete [] data;
          }
          // Standard Swap to facilitate rule of three
          void swap(String&amp; other) throw ()
          {
              std::swap(len,  other.len);
              std::swap(data, other.data);
          }
  
          // New Stuff
          // Move Operators
          String(String&amp;&amp; rhs) throw()
              : len(0)
              , data(null)
          {
              rhs.swap(*this);
          }
          String&amp; operator=(String&amp;&amp; rhs) throw()
          {
              rhs.swap(*this);
              return *this;
          }
  };
  </code></pre>
  
  <p>Pretty bog standard I think.</p>
  
  <p>Then I tested my code like this:</p>
  
  <pre><code>int main()
  {
      String  a("Hi");
      a   = String("Test Move Assignment");
  }
  </code></pre>
  
  <p>Here the assignment to <code>a</code> should use the "Move Assignment" operator. But there is a clash with the "Standard Assignment" operator (which is written as your standard copy and swap).</p>
  
  <pre><code>&gt; g++ --version
  Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include/c++/4.2.1
  Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
  Target: x86_64-apple-darwin13.0.0
  Thread model: posix
  
  &gt; g++ -std=c++11 String.cpp
  String.cpp:64:9: error: use of overloaded operator '=' is ambiguous (with operand types 'String' and 'String')
      a   = String("Test Move Assignment");
      ~   ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  String.cpp:32:17: note: candidate function
          String&amp; operator=(String rhs)
                  ^
  String.cpp:54:17: note: candidate function
          String&amp; operator=(String&amp;&amp; rhs)
                  ^
  </code></pre>
  
  <p>Now I can fix this by modifying the "Standard Assignment" operator to:</p>
  
  <pre><code>    String&amp; operator=(String const&amp; rhs)
      {
          String copy(rhs);
          copy.swap(*this);
          return *this;
      }
  </code></pre>
  
  <p>But this is not good as it messes with the compiler's ability to optimize the copy and swap. See What is the copy-and-swap idiom? <a href="https://stackoverflow.com/a/3279550/14065">here</a> and <a href="https://stackoverflow.com/a/3279616/14065">here</a></p>
  
  <p>Am I missing something not so obvious?</p>