Given a file tmp.cpp containing:<br><br>void exit(int);<br>void exit(float);<br><br>template <typename T><br>struct Identity {<br> typedef T type;<br>};<br><br>template <class T1, class T2, class R><br>void f(const T1* obj, R (T2::*member)() const);<br>
<br>template <class T1, class T2, class R><br>void f( T1* obj, R (T2::*member)());<br><br>template <class R><br>void f(R (*function)());<br><br>template <class T1, class T2, class R, class P1><br>void f(const T1* obj, R (T2::*member)(P1) const, typename Identity<P1>::type p1);<br>
<br>template <class T1, class T2, class R, class P1><br>void f( T1* obj, R (T2::*member)(P1) , typename Identity<P1>::type p1);<br><br>template <class R, class P1><br>void f(R (*function)(P1), typename Identity<P1>::type p1);<br>
<br>template <class T1, class T2, class R, class P1, class P2><br>void f(const T1* obj, R (T2::*member)(P1, P2) const, typename Identity<P1>::type p1, typename Identity<P2>::type p2);<br><br>template <class T1, class T2, class R, class P1, class P2><br>
void f( T1* obj, R (T2::*member)(P1, P2) , typename Identity<P1>::type p1, typename Identity<P2>::type p2);<br><br>template <class R, class P1, class P2><br>void f(R (*function)(P1, P2), typename Identity<P1>::type p1, typename Identity<P2>::type p2);<br>
<br>void test() {<br> f(exit, 0);<br>}<br><br><br>When Clang emits the error about not finding a match for that call to f because exit is an overloaded function, Clang currently emits notes for all of the function template candidates in lexical order, to where the "closest" failing match is the 6th note of 9 with 3 candidates that require a different number of arguments listed before it:<br>
<br>tmp.cpp:37:2: error: no matching function for call to 'f'<br> f(exit, 0);<br> ^<br>tmp.cpp:10:6: note: candidate template ignored: failed template argument deduction<br>void f(const T1* obj, R (T2::*member)() const);<br>
     ^<br>tmp.cpp:13:6: note: candidate template ignored: failed template argument deduction<br>void f( T1* obj, R (T2::*member)());<br>     ^<br>tmp.cpp:16:6: note: candidate function template not viable: requires 1 argument, but 2 were provided<br>
void f(R (*function)());<br>     ^<br>tmp.cpp:19:6: note: candidate function template not viable: requires 3 arguments, but 2 were provided<br>void f(const T1* obj, R (T2::*member)(P1) const, typename Identity<P1>::type p1);<br>
     ^<br>tmp.cpp:22:6: note: candidate function template not viable: requires 3 arguments, but 2 were provided<br>void f( T1* obj, R (T2::*member)(P1) , typename Identity<P1>::type p1);<br>     ^<br>tmp.cpp:25:6: note: candidate template ignored: couldn't infer template argument 'R'<br>
void f(R (*function)(P1), typename Identity<P1>::type p1);<br>     ^<br>tmp.cpp:28:6: note: candidate function template not viable: requires 4 arguments, but 2 were provided<br>void f(const T1* obj, R (T2::*member)(P1, P2) const, typename Identity<P1>::type p1, typename Identity<P2>::type p2);<br>
     ^<br>tmp.cpp:31:6: note: candidate function template not viable: requires 4 arguments, but 2 were provided<br>void f( T1* obj, R (T2::*member)(P1, P2) , typename Identity<P1>::type p1, typename Identity<P2>::type p2);<br>
     ^<br>tmp.cpp:34:6: note: candidate function template not viable: requires 3 arguments, but 2 were provided<br>void f(R (*function)(P1, P2), typename Identity<P1>::type p1, typename Identity<P2>::type p2);<br>
     ^<br>1 error generated.<br><br><br>This small patch adds rankings to the different types of template deduction failure (all of the OverloadCandidates above have a base FailureKind of ovl_fail_bad_deduction), so that e.g. a candidate where a template argument could not be inferred is listed before a candidate that requires the wrong number of arguments. So for the above code example, the output becomes:<br>
<br>tmp.cpp:37:2: error: no matching function for call to 'f'<br> f(exit, 0);<br> ^<br>tmp.cpp:25:6: note: candidate template ignored: couldn't infer template argument 'R'<br>void f(R (*function)(P1), typename Identity<P1>::type p1);<br>
     ^<br>tmp.cpp:10:6: note: candidate template ignored: failed template argument deduction<br>void f(const T1* obj, R (T2::*member)() const);<br>     ^<br>tmp.cpp:13:6: note: candidate template ignored: failed template argument deduction<br>
void f( T1* obj, R (T2::*member)());<br>     ^<br>tmp.cpp:16:6: note: candidate function template not viable: requires 1 argument, but 2 were provided<br>void f(R (*function)());<br>     ^<br>tmp.cpp:19:6: note: candidate function template not viable: requires 3 arguments, but 2 were provided<br>
void f(const T1* obj, R (T2::*member)(P1) const, typename Identity<P1>::type p1);<br>     ^<br>tmp.cpp:22:6: note: candidate function template not viable: requires 3 arguments, but 2 were provided<br>void f( T1* obj, R (T2::*member)(P1) , typename Identity<P1>::type p1);<br>
     ^<br>tmp.cpp:28:6: note: candidate function template not viable: requires 4 arguments, but 2 were provided<br>void f(const T1* obj, R (T2::*member)(P1, P2) const, typename Identity<P1>::type p1, typename Identity<P2>::type p2);<br>
     ^<br>tmp.cpp:31:6: note: candidate function template not viable: requires 4 arguments, but 2 were provided<br>void f( T1* obj, R (T2::*member)(P1, P2) , typename Identity<P1>::type p1, typename Identity<P2>::type p2);<br>
     ^<br>tmp.cpp:34:6: note: candidate function template not viable: requires 3 arguments, but 2 were provided<br>void f(R (*function)(P1, P2), typename Identity<P1>::type p1, typename Identity<P2>::type p2);<br>
     ^<br>1 error generated.<br><br><br>While the text of the note still isn't particularly useful for figuring out what failed, it at least gives a little better clue as to where the problem lies (in this example, the problem is rooted in there being two different single-argument declarations of "exit"). Feedback is both welcome and desired, especially on the ranking of the different types of deduction failures.<br>
<br>Cheers,<br>Kaelyn<br>