C++引用绑定重载解析中,哪条规则优先排除限定转换?
foo(int*&)会被优先调用? 考虑以下代码:
void foo(int*& r); // (1) void foo(const int* const& r); // (2) int main() { int* p; foo(p); }
在所有测试的编译器实现中,这段代码都会调用(1),但我无法从C++标准中找到要求该结果的明确依据。
根据[over.ics.ref]/1的规定,两个引用绑定都属于恒等转换:int*&直接绑定到int*类型的左值,这一点很明确;而const int* const&同样直接绑定到int*类型的左值——它不会先把int*转换为临时的const int*,再绑定到这个临时对象上。
既然两个隐式转换序列都是恒等转换,重载解析本应产生歧义,除非存在能区分二者的决胜规则。
[over.ics.rank]/3.2.5似乎是可能适用的决胜规则:
S1和S2仅在限定转换([conv.qual])上存在差异,分别生成相似类型T1和T2,其中T1可通过限定转换为T2。
但目前尚不清楚它是否真的适用于此场景:在(2)的绑定过程中实际上并没有发生限定转换,只是引用的行为仿佛绑定到const int*一样;另外,S1和S2对应的是引用类型,而[conv.qual]/2规定相似性不适用于引用类型(不过我猜想定义仍暗示引用类型与自身相似)。
决胜规则[over.ics.rank]/3.2.6并不适用,它的条件之一是“引用所指类型除顶级cv限定符外完全相同”,但const int*和int*的差异在于非顶级cv限定符,不符合该条件。
我找不到其他相关的决胜规则,是不是遗漏了什么能证明(1)比(2)更优的标准依据?
CWG1374的问题描述似乎暗示[over.ics.rank]/3.2.5与此场景相关,所以可能只是该条款的措辞需要改进。
内容的提问来源于stack exchange,提问作者Brian Bi

