考虑以下C ++代码:
struct X {
operator int();
operator char();
};
struct Y {
operator int();
operator char();
};
void f(bool z) {
z ? X() : Y();
}
GCC编译成功。 lang发出错误:
错误:条件表达式不明确; 'X'和'Y'可以是 转换为几种常见类型
MSVC也给出错误:
错误C2446:“:”:没有从“ Y”到“ X”的转换
注意:没有可用的用户定义转换运算符可以执行此转换,否则无法调用该运算符
哪个编译器在这里正确,在这种情况下,C ++标准的相关部分是什么?我的猜测是[over.match.oper]是适用的,但是到目前为止我还无法从中找出预期的行为。
更新:如果我们将两个operator int()
都更改为其他类型,例如operator bool()
,然后GCC也会出现错误。也许有一些关于int
类型的特殊规则?
答案 0 :(得分:2)
我认为这里是[expr.cond]/6:
(重点是我的)
否则,结果为prvalue。如果第二个和第三个操作数不具有相同的类型,并且都具有(可能是cv限定的)类类型,则使用重载分辨率确定要应用于这些操作数的转换(如果有)([over。 match.oper],[over.built])。如果重载解析失败,则程序格式错误。否则,将应用由此确定的转换,并在本小节的其余部分中使用转换后的操作数代替原始操作数。
这意味着,给定X
和Y
这两种不同的类型,重载解决方案将尝试确定可以应用的任何转换。重载解决方案失败,因为X
和Y
都可以转换为多种类型。该程序格式不正确; lang是正确的。
请注意,重载解析失败,因为X
和Y
有多次转换,因此无法确定转换。这意味着即使在执行适当的转换后它们可能具有相同的类型,下面的代码仍然格式不正确。
struct X {
operator int();
};
struct Y {
operator int();
operator char();
};
void f(bool z) {
z ? X() : Y();
}
来自clang的错误消息:
prog.cc:11:7: error: conditional expression is ambiguous; 'X' and 'Y' can be converted to several common types z ? X() : Y(); ^ ~~~ ~~~