title: How can I read a variable number of values into a std::tuple?
body: <p>I'm working on code that uses BSD file descriptors to read and write values from and to a pipe (with the <code>read</code> and <code>write</code> calls). This is part of a simple IPC system where one process tells another to run a procedure and return a result. Most of the time there is only one return value, but a few procedures need to return more than one. In order to avoid having to do a new <code>struct</code> for each of them, I thought I could use <code>std::tuple</code>s.</p>
  
  <p>However, I had very little success creating a general way to read elements into a tuple. I am trying to read the values individually because the two processes don't have the same bitness (one is 64 bits and the other is 32 bits), and I'm concerned about different alignment requirements in the <code>tuple</code> structs that could cause them to be incompatible. This is what I tried:</p>
  
  <pre><code>template&lt;typename TTupleType&gt;
  struct TupleReader
  {
      int fd;
      TTupleType&amp; storage;
  
      TupleReader(int fd, TTupleType&amp; storage) : fd(fd), storage(storage)
      { }
  
      template&lt;size_t Index = std::tuple_size&lt;TTupleType&gt;::value - 1&gt;
      inline void Read()
      {
          Read&lt;Index - 1&gt;(fd);
          auto&amp; ref = std::get&lt;Index&gt;(storage);
          ::read(fd, &amp;ref, sizeof ref);
      }
  };
  </code></pre>
  
  <p>It obviously doesn't compile, because it tries to instantiate <code>Read&lt;-1&gt;</code> and the implementation of the STL I use catches <code>std::get&lt;-1&gt;</code> with a <code>static_assert</code>. However, it's illegal to specialize a templated function in a class scope, but since the parent <code>struct</code> is templated as well, it's not possible to specialize the method outside either. <code>template&lt;typename TTupleReader&gt; void TupleReader&lt;TTupleType&gt;::Read&lt;0&gt;()</code> is considered a partial specialization.</p>
  
  <p>So it looks like I'm caught in limbo with this approach. Does anyone see a way to do it?</p>