title: Is it intended by the C++ standards committee that in C++11 unordered_map destroys what it inserts?
body: <p>I've just lost three days of my life tracking down a very strange bug where unordered_map::insert() destroys the variable you insert. This highly non-obvious behaviour occurs in very recent compilers only: I found that clang 3.2-3.4 and GCC 4.8 are the <strong>only</strong> compilers to demonstrate this "feature".</p>
  
  <p>Here's some reduced code from my main code base which demonstrates the issue:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;memory&gt;
  #include &lt;unordered_map&gt;
  #include &lt;iostream&gt;
  
  int main(void)
  {
    std::unordered_map&lt;int, std::shared_ptr&lt;int&gt;&gt; map;
    auto a(std::make_pair(5, std::make_shared&lt;int&gt;(5)));
    std::cout &lt;&lt; "a.second is " &lt;&lt; a.second.get() &lt;&lt; std::endl;
    map.insert(a); // Note we are NOT doing insert(std::move(a))
    std::cout &lt;&lt; "a.second is now " &lt;&lt; a.second.get() &lt;&lt; std::endl;
    return 0;
  }
  </code></pre>
  
  <p>I, like probably most C++ programmers, would expect output to look something like this:</p>
  
  <pre><code>a.second is 0x8c14048
  a.second is now 0x8c14048
  </code></pre>
  
  <p>But with clang 3.2-3.4 and GCC 4.8 I get this instead:</p>
  
  <pre><code>a.second is 0xe03088
  a.second is now 0
  </code></pre>
  
  <p>Which might make no sense, until you examine closely the docs for unordered_map::insert() at <a href="http://www.cplusplus.com/reference/unordered_map/unordered_map/insert/" rel="noreferrer">http://www.cplusplus.com/reference/unordered_map/unordered_map/insert/</a> where overload no 2 is:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>template &lt;class P&gt; pair&lt;iterator,bool&gt; insert ( P&amp;&amp; val );
  </code></pre>
  
  <p>Which is a greedy universal reference move overload, consuming anything not matching any of the other overloads, and <em>move constructing</em> it into a value_type. So why did our code above choose this overload, and not the unordered_map::value_type overload as probably most would expect?</p>
  
  <p>The answer stares you in the face: unordered_map::value_type is a pair&lt;<em>const</em> int, std::shared_ptr> and the compiler would correctly think that a pair&lt;<em>int</em>, std::shared_ptr> isn't convertible. Therefore the compiler chooses the move universal reference overload, and that destroys the original, <strong>despite</strong> the programmer not using std::move() which is the typical convention for indicating you are okay with a variable getting destroyed. Therefore the insert destroying behaviour is in fact <em>correct</em> as per the C++11 standard, and older compilers were <em>incorrect</em>.</p>
  
  <p>You can probably see now why I took three days to diagnose this bug. It was not at all obvious in a large code base where the type being inserted into unordered_map was a typedef defined far away in source code terms, and it never occurred to anyone to check if the typedef was identical to value_type.</p>
  
  <p>So my questions to Stack Overflow:</p>
  
  <ol>
  <li><p>Why do older compilers not destroy variables inserted like newer compilers? I mean, even GCC 4.7 doesn't do this, and it's pretty standards conforming.</p></li>
  <li><p>Is this problem widely known, because surely upgrading compilers will cause code which used to work to suddenly stop working?</p></li>
  <li><p>Did the C++ standards committee intend this behaviour?</p></li>
  <li><p>How would you suggest that unordered_map::insert() be modified to give better behaviour? I ask this because if there is support here, I intend to submit this behaviour as a N note to WG21 and ask them to implement a better behaviour.</p></li>
  </ol>