title: void * to the nth element of std::tuple at runtime
body: <p>Let's say I have a <code>std::tuple&lt;T...&gt;</code> and I want to get access to its nth element efficiently, where n is only known at runtime. Since the types <code>T...</code> are heterogeneous, all I can get is a <code>void *</code> and I'm OK with that. Here's what I've arrived at:</p>
  
  <pre><code>template &lt;size_t ... Indexes, class Tuple&gt;
  void * get_element_pointer(std::index_sequence&lt;Indexes...&gt;, Tuple &amp; t, size_t idx) {
      static size_t offsets[] = {(size_t)(void *)&amp;std::get&lt;Indexes&gt;(t) - (size_t)(void *)(&amp;t)...};
      return (void *)((size_t)(void *)(&amp;t) + offsets[idx]);
  }
  </code></pre>
  
  <p>You then call it like:</p>
  
  <pre><code>get_element_pointer(std::index_sequence_for&lt;T...&gt;{}, some_tuple, some_index);
  </code></pre>
  
  <p>The gist of this is to create statically a <code>size_t</code> array <code>offsets</code> that contains the list of offsets of each tuple element. Then, at runtime, I can just lookup the offset and add it to the passed tuple.</p>
  
  <p>Two problems bug me with my solution:</p>
  
  <ol>
  <li><code>offsets</code> is created the first time this function is called, and it's created based on the tuple instance passed at the time. I find this a bit weird. I could create a bogus temporary of type <code>Tuple</code>, but it might not be default constructible. Alternatively, I could cast a <code>nullptr</code> to a <code>Tuple *</code>, but then the <code>std::get&lt;Indexes&gt;(*(Tuple *)(nullptr))</code> screams UB.</li>
  <li>The <code>(size_t)(void *)(&amp;t)</code> and <code>(void *)((size_t)(void *)(&amp;t) + offsets[idx])</code> pointer juggling is the only way I could find that stops the compiler from giving me warnings. I know pointer conversions can be tricky and non-trivial when you have virtual functions etc. So I'm worried that I might be missing something.</li>
  </ol>
  
  <p>Do you think my solution is acceptable? Can you think of a simpler solution with less pointer juggling?</p>