在研究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;
}
aint的转换可以通过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中有一个决胜局:



由于从intint(精确匹配等级)的标准转换顺序要好于从charint(促销等级)的标准转换顺序,因此第一个要胜过第二个,并且应该没有歧义-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/

10-11 00:46
查看更多