title: std::map::operator[] is more efficient than std::map::insert?
body: <p>I've learnt that <strong>operator[]</strong> is equivalent to</p>
  <pre><code>(*((this-&gt;insert(make_pair(k,mapped_type()))).first)).second
  </code></pre>
  <p>So if a key doesn't exist in the map, using <strong>operator[]</strong> is less efficient than using <strong>insert</strong>, right? Because there's one more step, default construct.</p>
  <p>So I wrote a demo to test, like this.</p>
  <pre class="lang-cpp prettyprint-override"><code>
  #include &lt;iostream&gt;
  #include &lt;map&gt;
  
  using namespace std;
  
  static int id = 0;
  
  class Foo
  {
  public:
      Foo()
          : _val(0)
      {
          _id = ++id;
          cout &lt;&lt; _id &lt;&lt; &quot; construct_no_param:&quot; &lt;&lt; _val &lt;&lt; endl;
      }
      Foo(int val)
          : _val(val)
      {
          _id = ++id;
          cout &lt;&lt; _id &lt;&lt; &quot; construct_has_param:&quot; &lt;&lt; _val &lt;&lt; endl;
      }
      Foo(Foo &amp;rhs)
          : _val(rhs._val)
      {
          _id = ++id;
          cout &lt;&lt; _id &lt;&lt; &quot; construct_copy:&quot; &lt;&lt; _val &lt;&lt; endl;
      }
      Foo(const Foo &amp;rhs)
          : _val(rhs._val)
      {
          _id = ++id;
          cout &lt;&lt; _id &lt;&lt; &quot; construct_const_copy:&quot; &lt;&lt; _val &lt;&lt; endl;
      }
      Foo &amp;operator=(Foo &amp;rhs)
      {
          _val = rhs._val;
          cout &lt;&lt; _id &lt;&lt; &quot; assign:&quot; &lt;&lt; _val &lt;&lt; endl;
      }
      Foo &amp;operator=(const Foo &amp;rhs)
      {
          _val = rhs._val;
          cout &lt;&lt; _id &lt;&lt; &quot; const_assign:&quot; &lt;&lt; _val &lt;&lt; endl;
      }
      ~Foo()
      {
          cout &lt;&lt; _id &lt;&lt; &quot; destruct:&quot; &lt;&lt; _val &lt;&lt; endl;
      }
  
      int _val;
      int _id;
  };
  
  int main() {
      map&lt;int, Foo&gt; m;
      const Foo f(2);
      cout &lt;&lt; &quot;-----&quot; &lt;&lt; endl;
      // m[1] = f;
      // m.insert(make_pair(1, f));
      cout &lt;&lt; &quot;-----&quot; &lt;&lt; endl;
      return 0;
  }
  </code></pre>
  <p>First, I used <strong>operator[]</strong></p>
  <pre><code>    m[1] = f;
  </code></pre>
  <p>And I got this:</p>
  <pre><code>1 construct_has_param:2
  -----
  2 construct_no_param:0
  3 construct_const_copy:0
  4 construct_const_copy:0
  3 destruct:0
  2 destruct:0
  4 assign:2
  -----
  1 destruct:2
  4 destruct:2
  </code></pre>
  <p>Then, I used <strong>insert</strong></p>
  <pre><code>    m.insert(make_pair(1, f));
  </code></pre>
  <p>And I got this:</p>
  <pre><code>1 construct_has_param:2
  -----
  2 construct_const_copy:2
  3 construct_const_copy:2
  4 construct_const_copy:2
  5 construct_const_copy:2
  4 destruct:2
  3 destruct:2
  2 destruct:2
  -----
  1 destruct:2
  5 destruct:2
  </code></pre>
  <p>The results are not correspond to what I'm expected. Why <code>insert</code> has more constructions? What's going on here?</p>
  <p>BTW, I use -O0 option to disable optimization, but I'm not sure if it works.</p>
  <p>gcc version 4.8.2 20131212 (Red Hat 4.8.2-8) (GCC)</p>