在研究this SO question的答案时出现了问题。考虑以下代码:
struct A{
operator char() const{ return 'a'; }
operator int() const{ return 10; }
};
struct B {
void operator<< (int) { }
};
int main()
{
A a;
B b;
b << a;
}
a
到int
的转换可以通过a.operator char()
后跟一个整数提升,也可以通过a.operator int()
后跟一个身份转换(即完全不进行转换)来实现。该标准规定(§13.3.3.1[over.best.ics]/p10,脚注省略,粗体显示;所有引号均来自N3936):在这里,
B::operator<<(int)
是唯一可行的候选者-因此是最佳可行的候选者,即使参数的转换序列是模棱两可的转换序列。因此,根据粗体语句,该调用应格式错误,因为“调用中参数之一的转换是不明确的”。但是,我测试过的编译器(g++,clang和MSVC)实际上均未报告错误,这是有道理的,因为通过重载分辨率选择了要调用的函数之后,该函数的“参数(8.3.5)应该被初始化(8.5、12.8) ,12.1)及其对应的
参数”(第5.2.2节[expr.call]/p4)。此初始化为复制初始化(第8.5节[dcl.init]/p15),根据第8.5节[dcl.init]/p17,结果为新一轮的过载解析,确定要使用的转换函数:
在这一轮的过载解决方案中,第13.3.3节[over.match.best]/p1中有一个决胜局:
由于从
int
到int
(精确匹配等级)的标准转换顺序要好于从char
到int
(促销等级)的标准转换顺序,因此第一个要胜过第二个,并且应该没有歧义-operator int()
定义的转换将是用于初始化,然后与§13.3.3.1[over.best.ics]/p10中的句子相矛盾,该句子说函数调用由于含糊不清。上面的分析有什么问题吗?还是这句话是标准中的错误?
最佳答案
在为用户定义的转换序列确定最佳的用户定义的转换时,我们有一个重载候选集。
§13.3.3/p1说:
这适用于
§13.3.3.1.2/p2
因此,将包含operator int
的转换序列选择为最佳匹配。
最后,我将§13.3.3.1/p10改写为
关于c++ - 在重载解析中,选择使用歧义转换序列的函数是否必然导致调用格式错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25395056/