4

考虑以下 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++ 标准的相关部分是什么?我的猜测是 [over.match.oper] 是适用的,但到目前为止我无法从中找出预期的行为。

更新:如果我们将两者都更改operator int()为转换为其他类型,例如operator bool(),那么 GCC 也会出错。也许有一些关于int类型的特殊规则?

4

1 回答 1

2

我认为这里有说明,[expr.cond]/6

(强调我的)

否则,结果为纯右值。如果第二个和第三个操作数的类型不同,并且都具有(可能是 cv 限定的)类类型,则使用重载决议来确定要应用于操作数的转换(如果有)([over.match.oper ],[过度构建])。如果重载决议失败,则程序格式错误。否则,将应用如此确定的转换,并使用转换后的操作数代替本子条款其余部分的原始操作数。

这意味着,给定XY,这是两种不同的类型,重载解决方案将尝试确定可以应用的任何转换。重载解决方案失败,因为两者XY可以转换为多种类型。程序格式错误;叮当是正确的。

请注意,重载解析失败,因为有多个转换XY然后无法确定转换。这意味着即使在执行适当的转换后它们可能具有共同的类型,以下代码仍然是格式错误的。

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(); 
      ^ ~~~   ~~~
于 2018-08-01T03:55:41.247 回答