Partial order with L-value-ref

Why is this ambiguous?

template<class T> void g(T) {} // 1 template<class T> void g(T&) {} // 2 int main() { int q; g(q); } 

I understand that this is a partial ordering. And my, perhaps, erroneous thinking: any T & from # 2 can be placed in # 1, but not a single T from # 1 is legal in # 2. Such a partial order of work should work.

+6
source share
2 answers

OK I think this is what you are looking for. Without plunging into the double use of parameter comparisons and argument comparisons, the following jumps out in the standard:

C ++ 11 §14.8.2.4p5

Before performing partial ordering, some conversions are performed for the types used for partial ordering:

  • If P is a reference type, P is replaced by the type indicated.
  • If A is a reference type, A is replaced by the type indicated.

C ++ 11 §14.8.2.4p6 continues to talk about what happens when both are reference types, but this is not applicable here (albeit an interesting read). in your case, only one, therefore it is deprived. From there:

C ++ 11 §14.8.2.4p7

Remove all top-level cv qualifiers:

  • If P is a qualified class, P is replaced with a cv-unqualified version of P.
  • If A is a qualified class, A is replaced with a cv-unskilled version of A.

Now both are completely equal, and therefore you have an ambiguity, which, it seems to me, has hardened from C ++ 11 §14.8.2.4p10. The C ++ 11 text of §14.8.2.4p9 covers both types of links, which, again, do not apply here:

C ++ 11 §14.8.2.4p10

If for each type in question a given template is at least 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 specialized for any types, then this The template is more specialized than another template. Otherwise, no template is more specialized than another.

But reading the standard in this section is like decrypting the Greek language, so I can be outside the database. (no offense to the Greeks = P).

However, it made me think: "a const T& against a T , given the same invoke g(q) condition, should also be ambiguous if everything I just read is forcibly executed as written." Of course, I tried, and the same ambiguity was noted.
+7
source

Your reasoning is correct when these two types compete in the partial ordering of the partial specializations of class templates, and that is how they work.

But when a reference type is compared to a type without a reference, the general sense is that they are ambiguous in the call script, if nothing else makes a preference for the other. That is, the type of the link of the reference type does not matter when overload resolution is compared to another, therefore, the partial order also does not take it into account.

+4
source

All Articles