title: Compiler error C2664 using std::map and custom class as its value
body: <p>I've done a lot of searching on this issue but none of the answers helped. </p>
  
  <p>My setup</p>
  
  <ul>
  <li>Visual Studio 2017</li>
  <li>Windows 10</li>
  </ul>
  
  <p>I have a large codebase, where in one class Bar</p>
  
  <pre class="lang-cpp prettyprint-override"><code>
  // Bar.h
  
  class Bar {
  public:
     Bar();
     ~Bar();
  
  public:
      ... // a long list of other methods.
  
  private:
      std::map&lt;std::string, Foo&gt; m_foos;
  
  };
  
  </code></pre>
  
  <p>then in its implementation</p>
  
  <pre><code>// Bar.cpp
  
  Bar::Bar() {
     m_foos.insert(std::make_pair(std::string("id"), Foo()));              // Error 1
     m_foos.insert({std::string("id"), Foo()});                            // Error 2
     m_foos.insert(std::pair&lt;std::string, Foo&gt;(std::string("id"), Foo())); // Error 3
  }
  
  </code></pre>
  
  <p>Trying to compile the above code gives me:</p>
  
  <p>Error 1</p>
  
  <pre class="lang-cpp prettyprint-override"><code>error C2664: 'std::_Tree_iterator&lt;std::_Tree_val&lt;std::_Tree_simple_types&lt;_Ty&gt;&gt;&gt; std::_Tree&lt;std::_Tmap_traits&lt;_Kty,Foo,_Pr,_Alloc,false&gt;&gt;::insert(std::_Tree_const_iterator&lt;std::_Tree_val&lt;std::_Tree_simple_types&lt;_Ty&gt;&gt;&gt;,const std::pair&lt;const _Kty,Foo&gt; &amp;)': cannot convert argument 1 from 'std::pair&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt;,Foo&gt;' to 'std::pair&lt;const _Kty,_Ty&gt; &amp;&amp;'
  </code></pre>
  
  <p>Error 2</p>
  
  <pre class="lang-cpp prettyprint-override"><code>error C2664: 'std::_Tree_iterator&lt;std::_Tree_val&lt;std::_Tree_simple_types&lt;_Ty&gt;&gt;&gt; std::_Tree&lt;std::_Tmap_traits&lt;_Kty,Foo,_Pr,_Alloc,false&gt;&gt;::insert(std::_Tree_const_iterator&lt;std::_Tree_val&lt;std::_Tree_simple_types&lt;_Ty&gt;&gt;&gt;,const std::pair&lt;const _Kty,Foo&gt; &amp;)': cannot convert argument 1 from 'initializer list' to 'std::pair&lt;const _Kty,_Ty&gt; &amp;&amp;'
  </code></pre>
  
  <p>Error 3</p>
  
  <pre class="lang-cpp prettyprint-override"><code>error C2440: '&lt;function-style-cast&gt;': cannot convert from 'initializer list' to 'std::pair&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt;,Foo&gt;'
  
  </code></pre>
  
  <p>However, with the same setup and compiler, the following much-simplified code compiles successfully:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include "pch.h"
  #include &lt;iostream&gt;
  #include &lt;algorithm&gt;
  #include &lt;cstdio&gt;
  #include &lt;map&gt;
  #include &lt;string&gt;
  #include &lt;vector&gt;
  
  class Foo {
  public:
      Foo() { mi = 1; }
      ~Foo() {}
  
  private:
      int mi;
  };
  
  class MyFoo : public Foo {
  public:
      MyFoo() :Foo() {
          mj = 2;
          mk = nullptr;
      }
      ~MyFoo() {}
  
  private:
      int mj;
      int* mk;
  };
  
  class YourFoo : public Foo {
  public:
      YourFoo() :Foo() { mj = 2; }
      ~YourFoo() {}
  
  private:
      int mj;
  };
  
  int main()
  {
      std::map&lt;int, Foo&gt; yourmap;
      yourmap.insert(std::make_pair(3, Foo()));
      yourmap.insert({ 4, Foo() });
      yourmap.insert(std::pair&lt;int, Foo&gt;(5, Foo()));
  
  }
  </code></pre>
  
  <p>Where am I wrong?</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>So I can finally reproduce it. It's due to the fact that the offending class hierarchy removed their copy constructors and <code>operator =</code>.</p>
  
  <p>The modified example can reproduce the errors.</p>
  
  <pre><code>#include "pch.h"
  #include &lt;iostream&gt;
  #include &lt;algorithm&gt;
  #include &lt;cstdio&gt;
  #include &lt;map&gt;
  #include &lt;string&gt;
  #include &lt;vector&gt;
  
  class Foo {
  public:
      Foo() { mi = 1; }
      ~Foo() {}
  
      // NO COPIES.   
      Foo(const Foo &amp;) = delete;
      Foo&amp; operator = (const Foo &amp;) = delete;
  
  private:
      int mi;
  };
  
  class MyFoo : public Foo {
  public:
      MyFoo() :Foo() {
          mj = 2;
          mk = nullptr;
      }
      ~MyFoo() {}
  
      // NO COPIES.
      MyFoo(const MyFoo &amp;) = delete;
      MyFoo&amp; operator = (const MyFoo &amp;) = delete;
  
  private:
      int mj;
      int* mk;
  };
  
  class YourFoo : public Foo {
  public:
      YourFoo() :Foo() { mj = 2; }
      ~YourFoo() {}
  
      // NO COPIES.
      YourFoo(const YourFoo &amp;) = delete;
      YourFoo&amp; operator = (const YourFoo &amp;) = delete;
  
  private:
      int mj;
  };
  
  
  int main()
  {
      std::map&lt;int, Foo&gt; yourmap;
      yourmap.insert(std::make_pair(3, Foo()));
      yourmap.insert({ 4, Foo() });
      yourmap.insert(std::pair&lt;int, Foo&gt;(5, Foo()));
  
  }
  </code></pre>
  
  <p>So I guess the problem is that <code>std::map</code> must copy elements into its memory space. Then it just bumps into classes without copy constructors and complains. But the error messages are so misleading that I just can't figure out. The actual class hierarchy is pretty huge, so I didn't see those deleted parts. Guess someone does not want these things duplicated.</p>
  
  <p>If anybody can instruct how to decipher the compiler error messages near the beginning of my question so that I may get a better idea where to look, it would be greatly appreciated!</p>