title: Distinguishing r- and l-value references as template arguments
body: <p>Let's consider the following example:</p>
  <pre><code>void f(int&amp;&amp; i)
  { }
  
  template &lt;typename ... X, typename ... Y&gt;
  void g(void(*p)(X&amp;&amp;..., Y&amp;...))
  { }
  
  int main()
  {
      g(f);
      return 0;
  }
  </code></pre>
  <p>Compilation fails with error</p>
  <pre><code>&lt;source&gt;:10:7: error: invalid conversion from 'void (*)(int&amp;&amp;)' to 'void (*)(int&amp;)' [-fpermissive]
     10 |     g(f);
        |       ^
        |       |
        |       void (*)(int&amp;&amp;)
  &lt;source&gt;:5:14: note:   initializing argument 1 of 'void g(void (*)(X&amp;&amp; ..., Y&amp; ...)) [with X = {}; Y = {int}]'
      5 | void g(void(*p)(X&amp;&amp;..., Y&amp;...))
        |        ~~~~~~^~~~~~~~~~~~~~~~~
  </code></pre>
  <p>Demo on <a href="https://godbolt.org/z/qjMjv5bG4" rel="nofollow noreferrer">godbolt</a>.</p>
  <p>Apparently on deducing the template arguments all the function arguments produce ordinary l-value references while the set of r-value references remains empty (contrasting my own expectations) – but why?</p>
  <p>Side note: The problem that originally led to this question is solved by other means (recursive variadic template function producing a tuple) in the meanwhile, thus no XY-problem; asking out of curiosity – still would appreciate any other elegant solution which does <em>not</em> involve introducing tuples to the functions in question (<code>f</code> in above example).</p>