string move assignment exchange of values
<p>I was programming some test cases an noticed an odd behaviour.</p>

<p>An move assignment to a string did not erase the value of the first string, but assigned the value of the target string.</p>

<p>sample code:</p>

<pre><code>#include &lt;utility&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;

int main(void) {
  std::string a = "foo";
  std::string b = "bar";
  std::cout &lt;&lt; a &lt;&lt; std::endl;
  b = std::move(a);
  std::cout &lt;&lt; a &lt;&lt; std::endl;

  return 0;
}
</code></pre>

<p>result:</p>

<pre><code>$ ./string.exe
foo
bar
</code></pre>

<p>expected result:</p>

<pre><code>$ ./string.exe
foo
</code></pre>

<p>So to my questions:</p>

<ul>
<li>Is that intentional?</li>
<li>Does this happen only with strings and/or STL objects?</li>
<li>Does this happen with custom objects (as in user defined)?</li>
</ul>

<p>Environment:
Win10 64bit
msys2
g++ 5.2</p>

<p><strong>EDIT</strong></p>

<p>After reading the possible duplicate answer and the answer by @OMGtechy
i extended the test to check for small string optimizations.</p>

<pre><code>#include &lt;utility&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;cinttypes&gt;
#include &lt;sstream&gt;

int main(void) {
  std::ostringstream oss1;
  oss1 &lt;&lt; "foo ";
  std::ostringstream oss2;
  oss2 &lt;&lt; "bar ";
  for (std::uint64_t i(0);;++i) {
    oss1 &lt;&lt; i % 10;
    oss2 &lt;&lt; i % 10;
    std::string a = oss1.str();
    std::string b = oss2.str();
    b = std::move(a);
    if (a.size() &lt; i) {
      std::cout &lt;&lt; "move operation origin was cleared at: " &lt;&lt; i &lt;&lt; std::endl;
      break;
    }
    if (0 == i % 1000)
      std::cout &lt;&lt; i &lt;&lt; std::endl;
  }

  return 0;
}
</code></pre>

<p>This ran on my machine up to 1 MB, which is not a small string anymore.
And it just stopped, so i could paste the source here (Read: i stopped it).</p>