多隐式转换运算符 考虑下面的C++代码: struct X { operator int(); operator char(); }; struct Y { operator int(); operator char(); }; void f(bool z) { z ? X() : Y(); }
GCC成功地编译了它。Clang给出了一个错误: 错误:条件表达式不明确;'X'和Y'可以是 转换为几种常见类型 MSVC还提供了一个错误: 错误C2446:“:”:没有从“Y”到“X”的转换 注意:没有可执行此转换的用户定义的转换运算符,或者无法调用该运算符多隐式转换运算符 考虑下面的C++代码: struct X { operator int(); operator char(); }; struct Y { operator int(); operator char(); }; void f(bool z) { z ? X() : Y(); },c++,language-lawyer,clang++,conditional-operator,conversion-operator,C++,Language Lawyer,Clang++,Conditional Operator,Conversion Operator,GCC成功地编译了它。Clang给出了一个错误: 错误:条件表达式不明确;'X'和Y'可以是 转换为几种常见类型 MSVC还提供了一个错误: 错误C2446:“:”:没有从“Y”到“X”的转换 注意:没有可执行此转换的用户定义的转换运算符,或者无法调用该运算符 编译器在这里是正确的,在这种情况下C++标准的相关部分是什么?我的猜测是[over.match.oper]是适用的,但到目前为止,我无法从中找出预期的行为 更新:如果我们同时更改运算符int()以转换为其他类型,例如运算符bool(),那
编译器在这里是正确的,在这种情况下C++标准的相关部分是什么?我的猜测是[over.match.oper]是适用的,但到目前为止,我无法从中找出预期的行为
更新:如果我们同时更改运算符int()
以转换为其他类型,例如运算符bool()
,那么GCC也会给出一个错误。也许关于int
类型有一些特殊的规则?我想这里已经说明了:
(强调矿山)
否则,结果是一个pr值。如果第二个和第三个操作数的类型不同,并且其中一个具有(可能是cv限定的)类类型,重载解析用于确定要应用于操作数的转换(如果有)([over.match.oper],[over.build])。如果重载解析失败,则程序格式错误。否则,将应用由此确定的转换,并在本子条款的其余部分使用转换后的操作数代替原始操作数
这意味着,给定两种不同类型的X
和Y
,重载解决方案将尝试确定可以应用的任何转换。重载解决方案失败,因为X
和Y
都可以转换为多种类型。该计划形式不合理;叮当声是正确的
请注意,重载解析失败,因为X
和Y
存在多个转换,因此无法确定转换。这意味着,即使在执行适当的转换后,它们可能具有公共类型,以下代码仍然是格式错误的
struct X {
operator int();
};
struct Y {
operator int();
operator char();
};
void f(bool z) {
z ? X() : Y();
}
错误消息来自:
我相信gcc的行为是正确的。在
bool
情况下,它是不明确的,因为bool
toint
和char
toint
是相等的
prog.cc:11:7: error: conditional expression is ambiguous; 'X' and 'Y' can be converted to several common types
z ? X() : Y();
^ ~~~ ~~~