title: Overloading functions taking auto&&
body: <p>I'm able to overload functions with generic template arguments, such as this example:</p>
  <pre><code>#include &lt;iostream&gt;
  
  template&lt;typename... Args&gt;
  void
  f(Args...)
  {
    std::cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; &quot;\n&quot;;
  }
  
  class S {};
  
  template&lt;typename... Args&gt;
  void
  f(const S&amp;, Args...)
  {
    std::cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; &quot;\n&quot;;
  }
  
  int
  main()
  {
    f(1, 2, 3);
    f(S{}, 2);
  }
  </code></pre>
  <p>The output is</p>
  <pre><code>void f(Args...) [Args = &lt;int, int, int&gt;]
  void f(const S &amp;, Args...) [Args = &lt;int&gt;]
  </code></pre>
  <p>That is, the overload is called when the first argument is of type <code>S</code>, which is what I expected.</p>
  <p>If I change this to use <code>auto&amp;&amp;...</code> instead of templates, the behavior is no longer what I expected:</p>
  <pre><code>#include &lt;iostream&gt;
  
  void
  f(auto&amp;&amp;...)
  {
    std::cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; &quot;\n&quot;;
  }
  
  class S {};
  
  void
  f(const S&amp;, auto&amp;&amp;...)
  {
    std::cout &lt;&lt; __PRETTY_FUNCTION__ &lt;&lt; &quot;\n&quot;;
  }
  
  int
  main()
  {
    f(1, 2, 3);
    f(S{}, 2);
  }
  </code></pre>
  <p>Here, the output is</p>
  <pre><code>void f(auto &amp;&amp;...) [auto:1 = &lt;int, int, int&gt;]
  void f(auto &amp;&amp;...) [auto:1 = &lt;S, int&gt;]
  </code></pre>
  <p>That is, the overload is not called – the first function is called in both cases.</p>
  <p>This leads to two questions:</p>
  <ol>
  <li><p>What are the rules for functions taking <code>auto&amp;&amp;...</code> with respect to overloading?</p>
  </li>
  <li><p>What is the correct way to write the overloaded function so that the behavior is the same as the template version?</p>
  </li>
  </ol>