Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare two standard conversion sequences use the rank of contained conversions

#include <iostream>
void g(int*);  //#1
void g(int (&arr)[2]);  //#2

void f(int*);  //#3
void f(int const*);  //#4
int main(){
  int arr[2] ={0};
  f(arr);    // choose #3
  g(arr);  //ambiguous
}

Consider the above code, #3 is seleteced for f(ptr), however, g(arr) gives a ambiguous diagnostic.

The rule for choosing the best function is defined as:

Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if

  • S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by [over.ics.scs], excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence) or, if not that

So take a look at over.ics.scs#3

These are used to rank standard conversion sequences. The rank of a conversion sequence is determined by considering the rank of each conversion in the sequence and the rank of any reference binding.

According to my understanding of the above rule, I can understand why #3 is the best overload for f(ptr), that is:

Given S1 as (arr => int*):

Array-to-pointer conversion -> (identity conversion)  
^^^^^^^^^^^^^^^^^^^^^^^^^^^    ^^^^^^^^^^^^^^^^^^^^^                   
     int[2] => int*             int* => int* 

while given S2 as (ptr => int const*)

Array-to-pointer conversion -> Qualification conversions ->  identity conversion   
^^^^^^^^^^^^^^^^^^^^^^^^^^^    ^^^^^^^^^^^^^^^^^^^^^^^^^     ^^^^^^^^^^^^^^^^^^^ 
     int[2] => int*               int* => int const*           int const* => int const* 

Since identity conversion is a proper subsequence of Qualification conversions, hence S1 is better than S2. So, #3 is selected by overload resolution for f(ptr).

When I use a similar process to determine which is best for g(arr), I encounter an issue.

Again, given S1 as (arr => int*)

Array-to-pointer conversion -> identity conversion  
^^^^^^^^^^^^^^^^^^^^^^^^^^^    ^^^^^^^^^^^^^^^^^^^ 
      int[2] => int*              int* => int*

while given S2 as(arr => int (&arr)[2])

When a parameter of reference type binds directly to an argument expression, the implicit conversion sequence is the identity conversion, unless the argument expression has a type that is a derived class of the parameter type, in which case the implicit conversion sequence is a derived-to-base Conversion

identity conversion
^^^^^^^^^^^^^^^^^^^
  bind to reference   

Here, identity conversion of S2 is a proper subsequence of Array-to-pointer conversion of S1, hence it should be better than S1, why the compiler complained g(arr) is an ambiguous invocation?

Do I have any misreading about how to rank the standard conversion sequences? How to compare two standard ICS (rank of the contained conversion)?

like image 504
xmh0511 Avatar asked Dec 11 '20 08:12

xmh0511


1 Answers

The key point is here:

S1 is a proper subsequence of S2 (comparing the conversion sequences in the canonical form defined by [over.ics.scs], excluding any Lvalue Transformation; the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence) or, if not that

That means, for function call g(arr), all Array-to-pointer conversion are not used to determine the rank. In other words, from type int[2] to type int*, there's only an identity conversion that used to determine the rank. Hence, S1 of void g(int*); and S2 of void g(int (&arr)[2]); are indistinguishable ICS, hence the compiler gives an ambiguous error.

As a contrast, the conversions for void f(int*); and void f(int const*); used to compare rank are identity conversion and qualification conversion, respectively.

According to the rule:

the identity conversion sequence is considered to be a subsequence of any non-identity conversion sequence

Hence, Qualification conversion is considered to have a worse rank than that of identity conversion. So, void f(int*) wined the competition.

like image 112
xmh0511 Avatar answered Sep 21 '22 12:09

xmh0511