Consider
void foo(int*& r); // (1)
void foo(const int* const& r); // (2)
int main() {
int* p;
foo(p);
}
This calls (1) in all implementations I tested but I can't figure out what in the C++ standard requires this result.
[over.ics.ref]/1 implies that both reference bindings rank as identity conversions. int*&
binds directly to an lvalue of type int*
(obviously), and const int* const&
also binds directly to an lvalue of type int*
. (It doesn't convert the int*
to a temporary const int*
and bind to the temporary.)
Since both implicit conversion sequences are identity conversions, the overload resolution will be ambiguous unless there is a tie-breaker rule that distinguishes them.
[over.ics.rank]/3.2.5 might be the tie-breaker intended to apply to this situation:
S1
andS2
differ only in their qualification conversion ([conv.qual]) and yield similar typesT1
andT2
, respectively, whereT1
can be converted toT2
by a qualification conversion.
However, it's not clear that it actually applies. There is not actually a qualification conversion in (2); the reference simply binds to the int*
as if it were a const int*
. Also, S1
and S2
yield reference types, and similarity does not apply to reference types (though I guess the definition still implies that a reference type is similar to itself).
Tie-breaker [over.ics.rank]/3.2.6 doesn't apply; one of its conditions is "the types to which the references refer are the same type except for top-level cv-qualifiers"; but const int*
and int*
differ in a non-top-level cv-qualifier.
I don't see any other tie-breaker rule that is remotely relevant. Did I miss something that implies that (1) is better than (2)?
The issue description of CWG1374 seems to allude to [over.ics.rank]/3.2.5 being relevant, so perhaps the issue is simply that that bullet's wording needs to be improved.
As user17732522 pointed out, the lack of a rule was an oversight while resolving CWG2352.
I raised this with CWG, and it was agreed that there was an oversight. The result is CWG2803, which adds the missing wording.