title: Which is the most specialized function template in the context of taking the address?
body: <p>Consider this <a href="https://godbolt.org/z/66Kx54e9K" rel="noreferrer">example</a></p>
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;iostream&gt;
  template&lt;class T&gt;
  void fun(T&amp;){  //#1
      std::cout&lt;&lt;&quot;selected\n&quot;;
  }
  
  template&lt;class T&gt;
  void fun(T&amp;&amp;){}  //#2
  
  int main() {
      void(*ptr)(int&amp;) = &amp;fun;  //#3
  }
  </code></pre>
  <p>Both GCC and Clang report an error with the diagnosis &quot;ambiguous&quot;. According to [temp.deduct.funcaddr#1], such two function templates are all viable in <code>#3</code>. Hence, [over.over#5] needs to apply here</p>
  <blockquote>
  <p>Any given function template specialization F1 is eliminated if the set contains a second function template specialization whose function template is more specialized than the function template of F1 according to the partial ordering rules of [temp.func.order].</p>
  </blockquote>
  <p>To judge which is more specialized between <code>#1</code> and <code>#2</code>, [temp.deduct.partial#3.3] applies to them</p>
  <blockquote>
  <p>The types used to determine the ordering depend on the context in which the partial ordering is done:</p>
  <blockquote>
  <ul>
  <li>[...]</li>
  <li>In <strong>other contexts the function template's function type</strong> is used.</li>
  </ul>
  </blockquote>
  </blockquote>
  <p>Hence, the P and A used to participate in <strong>partial ordering</strong> should be the function type of that two function templates, respectively. Take the function type of <code>#2</code> as P and the function type of <code>#1</code> as A. Deduce <code>P</code> from <code>A</code> is successful as per [temp.deduct.type#10]</p>
  <blockquote>
  <p>If P and A are function types that originated from deduction when taking the address of a function template ([temp.deduct.funcaddr]) or when deducing template arguments from a function declaration ([temp.deduct.decl]) and Pi and Ai are parameters of the top-level parameter-type-list of P and A, respectively, Pi is adjusted if it is a forwarding reference ([temp.deduct.call]) and Ai is an lvalue reference, in which case the type of Pi is changed to be the template parameter type (i.e., T&amp;&amp; is changed to simply T).</p>
  </blockquote>
  <p>Conversely, Since we cannot deduce <code>T&amp;</code> from <code>T&amp;&amp;</code>, hence the function template at <code>#1</code> is more specialized than the function template at <code>#2</code>. Hence the specialization of <code>#2</code> should be eliminated from the set. Ultimately, the set only contains exactly one specialization of <code>#1</code>. It should be unambiguous here. Why do GCC and Clang say the taking address is ambiguous?</p>