title: std::map sequencing of operator[] and size()
body: <p>I have a <code>std::map</code> and trying to fill it with pairs <code>(name, id)</code>. The <code>id</code> field is simply generated from map's <code>size()</code>. Here's a simplified version:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;map&gt;
  
  struct A {
      std::string name;
      int id;
      A(const std::string &amp;s) : name(s), id(-1) { }
  };
  
  class Database {
      std::map&lt;std::string, int&gt; ids;
  public:
      void insert(A *item) {
          ids[item-&gt;name] = item-&gt;id = ids.size();
      }
      void dump() const {
          for (std::map&lt;std::string, int&gt;::const_iterator i = ids.begin(); i != ids.end(); i++)
              std::cout &lt;&lt; i-&gt;second &lt;&lt; ". " &lt;&lt; i-&gt;first &lt;&lt; std::endl;
      }
  };
  
  int main(int argc, char **agrv) {
      A a("Test");
      Database db;
      db.insert(&amp;a);
      db.dump();
      return 0;
  }
  </code></pre>
  
  <p>The problem is that different compilers treat the <code>ids[item-&gt;name] = item-&gt;id = ids.size()</code> part differently. Clang++ produces</p>
  
  <pre><code>item-&gt;id = ids.size(); // First item gets 0
  ids[item-&gt;name] = item-&gt;id;
  </code></pre>
  
  <p>when g++ does something like</p>
  
  <pre><code>ids.insert(std::pair&lt;std::string, int&gt;(item-&gt;name, 0));
  item-&gt;id = ids.size(); // First item gets 1
  ids[item-&gt;name] = item-&gt;id;
  </code></pre>
  
  <p>So, is this code valid (from the STL perspective) or it is as evil as <code>i = ++i + ++i</code>?</p>