排序时指针类型的身份转换是否视为资格转换

Is an identity conversion of pointer type be considered as qualification conversion when ranking

void fun(int*);  // #1
void fun(int const*);  //#2
int main(){
  int* ptr = nullptr;
  fun(ptr);
}

考虑以上示例,重载决议应 select #1#2 中的最佳可行函数。这是this question的一个分支,即[over.ics.rank#3.2.1]和[over.ics.rank#3.2.5]之间的模糊部分。

相关规则为:

over.ics.rank#3.2.1

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

IMO,#1S1有身份转换,而#2S2有资格转换,上面的规则好像是说Identity conversion 优于任何具有完全匹配排名的非身份转换。

不过,还有一条相关的规则对应于这种情况,那就是:
over.ics.rank#3.2.5

S1 and S2 differ only in their qualification conversion ([conv.qual]) and yield similar types T1 and T2, respectively, where T1 can be converted to T2 by a qualification conversion.

IMO,这个规则好像说S1S2都有一个资格转换但是这些转换是不同的T1可以通过限定转换转换为 T2

在我的例子中,从int*int const*绝对是一个资格转换。但是,一个edge-case是从int*int*,这个转换算身份转换还是资格转换?根据conv.qual#3的定义,可以。不过严格来说应该叫身份转换.

问题 1:

我对规则[over.ics.rank#3.2.5]的理解对吗?或者,是否意味着,当T1可以通过限定转换转换为T2时,S1可能有一个空转换(例如身份转换)? (包括指针的身份转换)

Q问题2:

指针类型的恒等转换是限定转换还是恒等转换?换句话说,[over.ics.rank#3.2.1] 或 [over.ics.rank#3.2.5] 是否适用于我的示例?

int*int* 的标准转换序列 包含限定转换。

[over.ics.best.general]/8 明确指出了这一点:

If no conversions are required to match an argument to a parameter type, the implicit conversion sequence is the standard conversion sequence consisting of the identity conversion ([over.ics.scs]).

从其他段落也可以推断。例如,参见 [over.best.ics.general]/1:

An implicit conversion sequence is a sequence of conversions used to convert an argument in a function call to the type of the corresponding parameter of the function being called. The sequence of conversions is an implicit conversion as defined in [conv], which means it is governed by the rules for initialization of an object or reference by a single expression ([dcl.init], [dcl.init.ref]).

和[over.ics.best.general]/6:

When the parameter type is not a reference, the implicit conversion sequence models a copy-initialization of the parameter from the argument expression. The implicit conversion sequence is the one required to convert the argument expression to a prvalue of the type of the parameter.
...

也就是说,int* -> int* 的正确隐式转换序列是根据语言规则,通常在复制 int* 时形成的序列- 从 int* 初始化。在这种情况下,[dcl.init.general]/16.9 适用:

Otherwise, the initial value of the object being initialized is the (possibly converted) value of the initializer expression. A standard conversion sequence ([conv]) will be used, if necessary, to convert the initializer expression to the cv-unqualified version of the destination type; no user-defined conversions are considered. If the conversion cannot be done, the initialization is ill-formed. When initializing a bit-field with a value that it cannot represent, the resulting value of the bit-field is implementation-defined.

不需要转换,因为 int*int* 已经是同一类型,所以不需要转换。它不是从 int* 到自身的限定转换。

这意味着[over.ics.rank]/3.2.1肯定是决定性的:S1是身份转换序列(不是由冗余限定转换组成的隐式转换序列)所以它是S2.