The first example is
template <class... T> struct V {};
template <class... Ts, class... Us> void Foo(V<Ts...>, V<Us&...>) {} // #3
template <class... Us> void Foo(V<>, V<Us&...>) {} // #4
void h() {
Foo(V<>(), V<>());
}
The above example is mentioned in CWG2235. In that paper, which says #4 is a better candidate. However, GCC and Clang have disagreements with this example. I think GCC is correct, my reason is, Take #4 as argument template and #3 as parameter template, the deductions are successful for each pair that is used to determine the ordering.
Instead, when take #3 as argument template and #4 as parameter template, the following rules is applied here
temp.deduct.type#9
During partial ordering, if Ai was originally a pack expansion:
- if P does not contain a template argument corresponding to Ai then Ai is ignored;
- otherwise, if Pi is not a pack expansion, template argument deduction fails.
That means the deduction is still successful for each pair. Finally, there's no special rule in section [temp.deduct.partial] to determine which is more specialized. Hence, it should be ambiguous here which should be GCC's opinion.
For this example, if I have some misunderstanding, please point it out.
Now, consider a bit complex example that GCC and Clang also disagree.
#include <iostream>
struct A { };
template<class T>
struct B {
template<class R>
int operator*(R) {
std::cout<<"#1\n";
return 0;
}
};
template<class R>
int operator*(B<A>&&, R){
std::cout<<"#2\n";
return 0;
}
int main(){
B<A>{} * 0;
}
GCC considers the example as ambiguous while Clang chooses #1. This time, I'm still a proponent of GCC. My reason is
temp.func.order#3
For a function template M with cv-qualifiers cv that is a member of a class A:
- The type X(M) is “rvalue reference to cv A” if the optional ref-qualifier of M is && or if M has no ref-qualifier and the positionally-corresponding parameter of the other transformed template has rvalue reference type; if this determination depends recursively upon whether X(M) is an rvalue reference type, it is not considered to have rvalue reference type.
It means that the implicit parameter of #1 should be B<A>&& during the ordering partial. Which is identical with the first parameter in #2 and the other pair can also be deduced successfully in both directions. Hence, #1 and #2 should be ambiguous here too.
In general, in these two examples, I agree with the result processed by GCC. If I misunderstand something, please point it out.