如何比较两个标准转换序列使用包含的转换的等级 [英] 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
}
考虑以上代码,将#3 选作 f(ptr)
,但是, g(arr)
给出一个模棱两可的
诊断.
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:
如果标准转换序列S1比标准转换序列S2更好,那么
Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if
- S1是S2的适当子序列(以[over.ics.scs]定义的规范形式比较转换序列,不包括任何左值变换; 同一性转换序列被视为任何非左值的子序列)-身份转换顺序),或者,否则
- 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
因此,请查看 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.
根据我对上述规则的理解,我可以理解为什么#3
是 f(ptr)
的最佳重载,即:
According to my understanding of the above rule, I can understand why #3
is the best overload for f(ptr)
, that is:
将S1设为(arr => int *):
Given S1 as (arr => int*):
Array-to-pointer conversion -> (identity conversion)
^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
int[2] => int* int* => int*
同时给定S2为(ptr => int const *)
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*
由于身份转换
是 Quality conversions
的适当子序列,因此S1优于S2.因此,#3 是通过 f(ptr)
的重载分辨率选择的.
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)
.
当我使用类似的过程来确定哪个最适合 g(arr)
时,我遇到了一个问题.
When I use a similar process to determine which is best for g(arr)
, I encounter an issue.
同样,给定S1为(arr => int *)
Again, given S1 as (arr => int*)
Array-to-pointer conversion -> identity conversion
^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^
int[2] => int* int* => int*
同时给定S2为(arr => int(& arr)[2])
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
这里, S2
的身份转换
是 S1
的数组到指针转换
的适当子序列,因此它应该比 S1
更好,为什么编译器会抱怨 g(arr)
是模棱两可的调用?
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?
我对如何对标准转换序列进行排名有误读吗?如何比较两个标准ICS(包含的转化等级)?
Do I have any misreading about how to rank the standard conversion sequences? How to compare two standard ICS (rank of the contained conversion)?
推荐答案
关键点在这里:
S1是S2的适当子序列(比较[over.ics.scs]定义的规范形式的转换序列,不包括任何左值转换;同一性转换序列被认为是任何非同一性转换序列的子序列),或者如果不是这样的话
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
这意味着,对于函数调用 g(arr)
,所有数组到指针的转换都不用于确定排名.换句话说,从 int [2]
类型到 int *
类型,只有一个身份转换可用于确定排名.因此, void g(int *);的S1和
void g(int(& arr)[2]); 的S2是无法区分的ICS,因此编译器给出一个模棱两可的错误.
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.
相反,用于比较排名的 void f(int *);
和 void f(int const *);
的转换是身份转换
和资格转换
.
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.
根据规则:
身份转换序列被视为任何非身份转换序列的子序列
因此,
因此,资格转换
的排名要比身份转换
的排名低.因此, void f(int *)
刺激了比赛.
Hence, Qualification conversion
is considered to have a worse rank than that of identity conversion
. So, void f(int*)
wined the competition.
这篇关于如何比较两个标准转换序列使用包含的转换的等级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!