Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

partial ordering with L-value-ref

Why this is 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 partial ordering context. And my, possibly erroneous, thinking is: any T& from #2 can be put in #1, but not any T from #1 is legit in #2. So partial ordering should work.

like image 774
Leonid Volnitsky Avatar asked Jan 22 '13 07:01

Leonid Volnitsky


1 Answers

OK. I think this is what you're looking for. Not diving into the twice-application of the parameter vs. argument type comparison, the following in the standard leaps out at me:

C++11 §14.8.2.4p5

Before the partial ordering is done, certain transformations are performed on the types used for partial ordering:

  • 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.

C++11 §14.8.2.4p6 goes on to talk about what happens when both are reference types, but that isn't applicable here (though also an interesting read). in your case, only one is, so it is stripped. From there:

C++11 §14.8.2.4p7

Remove any top-level cv-qualifiers:

  • 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.

Now both are completely equal, and thus you have your ambiguity, which I believe is solidified from C++11 §14.8.2.4p10. The text of C++11 §14.8.2.4p9 covers both being reference types which, again, is not the case here:

C++11 §14.8.2.4p10

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. Otherwise, neither template is more specialized than the other.

But reading the standard in this section is like deciphering greek to me, so I may be way off base. (no offense to the Greeks =P).

It did, however, make me think "a const T& against a T, given the same invoke condition g(q), should also be ambiguous if everything I just read is enforced as-written." Sure enough, I tried it, and the same ambiguity was flagged.

like image 146
WhozCraig Avatar answered Oct 16 '22 16:10

WhozCraig