------- Comment #2 from schaub-johannes at web dot de 2010-03-28 19:33 ------- I've done some analysis for this using the argument-deduction during partial ordering rules as clarified by http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#214:
template<typename T, typename U> void f(U&) { } // #1 template<typename T, typename U> void f(T const&) { } // #2 4 Each type from the parameter template and the corresponding type from the argument template are used as the types of P and A. Round 1, #1 -> #2: As: (X&) // #1 Ps: (T const&) // #2 Round 2, #2 -> #1: As: (X const&) // #2 Ps: (T&) // #1 If P is a reference type, P is replaced by the type referred to. If A is a reference type, A is replaced by the type referred to. => Round 1, #1 -> #2: As: (X) // #1 Ps: (T const) // #2 Round 2, #2 -> #1: As: (X const) // #2 Ps: (T) // #1 If both P and A were reference types (before being replaced with the type referred to above), determine which of the two types (if any) is more cv-qualified than the other; otherwise the types are considered to be equally cv-qualified for partial ordering purposes. The result of this determination will be used below. => ************* #2 more cv-qualified than #1 If P is a cv-qualified type, P is replaced by the cv-unqualified version of P. If A is a cv-qualified type, A is replaced by the cv-unqualified version of A. Round 1, #1 -> #2: As: (X) // #1 Ps: (T) // #2 Round 2, #2 -> #1: As: (X) // #2 Ps: (T) // #1 Using the resulting types P and A the deduction is then done as described in 14.9.2.5. If deduction succeeds for a given type, the type from the argument template is considered to be at least as specialized as the type from the parameter template. Round 1, T <- X Round 2, T <- X #1.param1 at least as specialized as #2.param1 and vice-versa. If, for a given type, deduction succeeds in both directions (i.e., the types are identical after the transformations above) and if the type from the argument template is more cv-qualified than the type from the parameter template (as described above) that type is considered to be more specialized than the other. Deduction succeeded in both rounds ("types" as in P/A pairs), but #2.param1 was more cv-qualified => #2.param1 more specialized than #1.param1 If for each type being considered a given template is at least as specialized for all types and more specialized for some set of types and the other template is not more specialized for any types or is not at least as specialized for any types, then the given template is more specialized than the other template. #2 is at least as specialized for all types and more specialized for #1.param1 and #1 is not more specialized for any types, so #2 is more specialized than #1. So, i think GCC should choose the one with the f(T const&) because that template is more specialized. Notice that the rules also say In most cases, all template parameters must have values in order for deduction to succeed, but for partial ordering purposes a template parameter may remain without a value provided it is not used in the types being used for partial ordering. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43559