title: Why a default constructor is needed using unordered_map and tuple?
body: <p>In the program below, I store some information in an hash table (std::unordered_map), the key is an object of the class RectData, the associated value is a tuple &lt;uint, RectData, enum&gt; and custom KeyHash and KeyEqual have been defined. </p>
  
  <p>Inserting a &lt;key,value&gt; pair without a default constructor gives two pages of error with gcc 4.9.2. The line with the first error is:</p>
  
  <pre><code>visited_info[rect0] = info0;
  </code></pre>
  
  <p>I double checked with MSVC++ 12.0, I also have error messages.</p>
  
  <p>When I add the default constructor, compilation is ok and the default constructor is called at run time. I could not understand  why a default constructor is needed for the class RectData ?</p>
  
  <p>Retrieving data from the hash table, using the [] operator, also requires a default constructor at compile time, but it is not called at run time, why ?</p>
  
  <pre><code>auto info = visited_info[rect];
  </code></pre>
  
  <p>Note: Changing the code with visited_info.emplace() and visited_info.find() solves the problem, but does not answer the question.</p>
  
  <p>Thanks for your answers.</p>
  
  <p>Full code is below.</p>
  
  <pre><code>#include &lt;boost/functional/hash.hpp&gt;
  #include &lt;tuple&gt;
  #include &lt;vector&gt;
  #include &lt;unordered_map&gt;
  #include &lt;iostream&gt;
  
  using uint = unsigned int;
  
  enum class Direction : int { left = 0, right = 1, up = 2, down = 3, null = 4 };
  
  class RectData {
   public:
    RectData(uint width, uint height)
        : width_(width), height_(height), datas_(width * height, 0) {
      total_ = width_ * height_;
    }
  
  
    // A default constructor must be defined!
    RectData() : RectData(0u, 0u) {
      std::cout &lt;&lt; "Calling the default constructor !!!" &lt;&lt; std::endl;
    }
  
    size_t hash() const {
      return boost::hash_value(datas_);
    }
  
    bool operator==(const RectData &amp;rect) const {
      return (width_ == rect.width_) &amp;&amp;
             (height_ == rect.height_) &amp;&amp;
             (datas_ == rect.datas_);
    }
  
    struct KeyHash {
      std::size_t operator()(const RectData &amp;rect) const {
        return rect.hash();
      }
    };
  
    struct KeyEqual {
      std::size_t operator()(const RectData &amp;r1, const RectData &amp;r2) const {
        return r1 == r2;
      }
    };
  
   private:
    uint width_;
    uint height_;
    std::vector&lt;uint&gt; datas_;
    uint total_;
  };
  
  using StoredInfo = std::tuple&lt;uint, RectData, Direction&gt;;
  
  int main() {
    std::unordered_map&lt;RectData, StoredInfo, RectData::KeyHash,
                       RectData::KeyEqual&gt; visited_info;
  
    RectData rect0(5u, 5u);
    RectData rect1(4u, 4u);
    RectData rect2(3u, 3u);
    RectData rect3(2u, 2u);
  
    StoredInfo info0 = std::make_tuple(10u, rect1, Direction::up);
    StoredInfo info1 = std::make_tuple(11u, rect2, Direction::down);
    StoredInfo info2 = std::make_tuple(12u, rect3, Direction::left);
    StoredInfo info3 = std::make_tuple(13u, rect0, Direction::right);
  
  
    // the line below requires a default RectData constructor!!! 
    visited_info[rect0] = info0;
  
    // default RectData constructor also needed here !!!
    visited_info[rect1] = std::move(info2);
  
    // but not needed here
    visited_info.insert(std::make_pair(rect2, info2));
  
    // and not needed here
    visited_info.emplace(rect3, info3);
  
    // but needed here and not called!!! 
    StoredInfo i1 = visited_info[rect1];
    std::cout &lt;&lt; "Verify (must be 11) = " &lt;&lt; std::get&lt;0&gt;(i1)
              &lt;&lt; std::endl;
  
    // but needed here and not called!!! 
    StoredInfo &amp;i2 = visited_info[rect2];
    std::cout &lt;&lt; "Verify (must be 12) = " &lt;&lt; std::get&lt;0&gt;(i2)
              &lt;&lt; std::endl;
  
  
    // and not needed here
    auto it = visited_info.find(rect3); 
    std::cout &lt;&lt; "Verify (must be 13) = " &lt;&lt; std::get&lt;0&gt;(it-&gt;second)
              &lt;&lt; std::endl;
  
  }
  </code></pre>