title: Merge tuple and integral instances into tuple of references
body: <p>I've encountered strange behavior when trying to construct a tuple of references from a mix of tuples and integral values.</p>
  
  <p>Given the following:</p>
  
  <pre><code>struct A { int v = 1; };
  struct B { int v = 2; };
  struct C { int v = 3; };
  A a;
  std::tuple&lt;B,C&gt; tpl;
  </code></pre>
  
  <p>I'm trying to create a third tuple which holds references to all instances, so that each instance's <code>v</code> will be assignable and readable through it.</p>
  
  <p>Seems simple enough using templates</p>
  
  <pre><code>template &lt;class Tuple, size_t... Is&gt;
  constexpr auto as_ref_impl(Tuple t, std::index_sequence&lt;Is...&gt;) {
      return std::tuple_cat(std::tie(std::get&lt;Is&gt;(t))...);
      // or
      // return std::make_tuple(std::ref(std::get&lt;Is&gt;(t))...);
  }
  
  template &lt;class...Args&gt;
  constexpr auto as_ref(std::tuple&lt;Args...&gt;&amp; t) {
      return as_ref_impl(t, std::index_sequence_for&lt;Args...&gt;{});
  }
  </code></pre>
  
  <p>and then</p>
  
  <pre><code>auto ref_tpl = std::tuple_cat(std::tie(a), as_ref(tpl));
  </code></pre>
  
  <p>which builds fine (in both versions).</p>
  
  <p>Unfortunately only the parts of the reference tuple (<code>ref_tpl</code>), which originate from integral values, can be assigned or read from successfully.</p>
  
  <p>I'm using <code>C++14</code> and <code>gcc 9.3.0</code>.</p>
  
  <p>Any ideas, or insight why this does not work, are very welcome!</p>
  
  <p><strong>Minimal working example:</strong></p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;tuple&gt;
  #include &lt;type_traits&gt;
  #include &lt;utility&gt;
  #include &lt;functional&gt;
  
  struct A { int v = 1; };
  struct B { int v = 2; };
  struct C { int v = 3; };
  A a;
  std::tuple&lt;B,C&gt; tpl;
  
  template &lt;class Tuple, size_t... Is&gt;
  constexpr auto as_ref_impl(Tuple t, std::index_sequence&lt;Is...&gt;) {
      //return std::tuple_cat(std::tie(std::get&lt;Is&gt;(t))...);
      return std::make_tuple(std::ref(std::get&lt;Is&gt;(t))...);
  }
  
  template &lt;class...Args&gt;
  constexpr auto as_ref(std::tuple&lt;Args...&gt;&amp; t) {
      return as_ref_impl(t, std::index_sequence_for&lt;Args...&gt;{});
  }
  
  int main() {
      using std::cout;
  
      auto ref_tpl = std::tuple_cat(std::tie(a), as_ref(tpl));
  
      // prints 1 2 3, as expected.
      cout &lt;&lt; a.v &lt;&lt; std::get&lt;0&gt;(tpl).v &lt;&lt; std::get&lt;1&gt;(tpl).v &lt;&lt; std::endl;
  
      std::get&lt;0&gt;(ref_tpl).v = 8; // works
      std::get&lt;1&gt;(ref_tpl).v = 9; // does not work
      std::get&lt;2&gt;(ref_tpl).v = 10; // does not work
  
      // should output 8 9 10 instead outputs 8 2 3
      cout &lt;&lt; a.v &lt;&lt; std::get&lt;0&gt;(tpl).v &lt;&lt; std::get&lt;1&gt;(tpl).v &lt;&lt; std::endl;
  
      // should output 8 9 10, instead outputs garbage.
      cout &lt;&lt; std::get&lt;0&gt;(ref_tpl).v &lt;&lt; std::get&lt;1&gt;(ref_tpl).v &lt;&lt; std::get&lt;2&gt;(ref_tpl).v &lt;&lt; std::endl;
  
      return 0;
  }
  </code></pre>