template <typename T>
void show(T&); // #1
template <typename T>
void show(T const&); // #2
int main()
{
int a = 0;
show(a); // #1 to be called
}
I'm confused about these partial ordering rules. Here are some quotes: [temp.deduct.partial]/5
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.
If both
P
andA
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.
Remove any top-level cv-qualifiers:
If
P
is a cv-qualified type,P
is replaced by the cv-unqualified version ofP
.If
A
is a cv-qualified type,A
is replaced by the cv-unqualified version ofA
.
Firstly, both void show(T&)
and void show(T const&)
could be called by passing an int
lvalue, so we need to use partial order rules to decide which function is more matched. Then, according to the above quotes, we do some transformations. Step 1:
T& => T #3
T const& => T const #4
Step 2:
T => T #5
T const => T #6
#5 => #6
, #6 => #5
, deduction succeeds in both directions.
Then the following rules work: [temp.deduct.partial]/9
If, for a given type, deduction succeeds in both directions (i.e., the types are identical after the transformations above) and both
P
andA
were reference types (before being replaced with the type referred to above):
if the type from the argument template was an lvalue reference and the type from the parameter template was not, the parameter type is not considered to be at least as specialized as the argument type;
otherwise, if the type from the argument template is more cv-qualified than the type from the parameter template (as described above), the parameter type is not considered to be at least as specialized as the argument type.
So #4
is more specialized then #3
. For a given value a
, #2
function should be called, but actually #1
function is called. Why? Is there something wrong with my understanding?