title: Rationale of template parameter pack expansion syntax
body: <p>Given the following helper functions</p>
  
  <pre><code>template &lt;typename ... Ts&gt;
  auto f(Ts&amp;&amp; ... args) {}
  
  template &lt;typename T&gt;
  auto g(T x) { return x; }
  </code></pre>
  
  <p><strong>1)</strong> We expand a template parameter pack as usual.</p>
  
  <pre><code>template &lt;typename ... Ts&gt;
  void test1(Ts&amp;&amp; ... args)
  {
      f(args...);
  }
  </code></pre>
  
  <hr>
  
  <p><strong>2)</strong> Here the expansion <code>...</code> occurs after the function call of <code>g()</code>. This is also reasonable, since <code>g()</code> is being called with each <code>args</code>:</p>
  
  <pre><code>template &lt;typename ... Ts&gt;
  void test2(Ts&amp;&amp; ... args)
  {
      f(g(args)...);
  }
  </code></pre>
  
  <hr>
  
  <p><strong>3)</strong> With the same logic I would expect <code>test3(Is, args...)...</code>, but no. You have to write <code>test3(Is..., args...)</code>:</p>
  
  <pre><code>template &lt;typename ... Ts&gt;
  void test3(size_t i, Ts&amp;&amp; ... args)
  {
      f(args...);
  }
  
  template &lt;typename ... Ts&gt;
  void test3(std::index_sequence&lt;Is...&gt;, Ts&amp;&amp; ... args)
  {
      // would expect test3(Is, args...)...;
      test3(Is..., args...);
  }
  </code></pre>
  
  <p>I know it, I use it, but well, I don't get it. The whole concept of template expansion is a form of expression folding. Not in the C++17 way, but in the sense that the subexpression before the <code>...</code> is being folded (or repeated if you like) in respect to the variadic parameter. In the <code>test3</code> case we are "folding" the expression <code>test3(Is, args...)</code> in respect to <code>Is</code>. Yet we have to write <code>test3(Is..., args...)</code> instead of <code>test3(Is, args...)...</code>.</p>
  
  <p>With this weird logic of the standard you could also write <code>f(g(args...))</code> instead of <code>f(g(args)...)</code> - however that's invalid. It looks like the language uses different logic in different contexts.</p>
  
  <p>What is the rationale behind the different syntax?</p>