多个隐式转换运算符

时间:2018-08-01 03:26:32

标签: c++ language-lawyer clang++ conditional-operator conversion-operator

考虑以下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类型的特殊规则?

1 个答案:

答案 0 :(得分:2)

我认为这里是[expr.cond]/6

(重点是我的)

  

否则,结果为prvalue。如果第二个和第三个操作数不具有相同的类型,并且都具有(可能是cv限定的)类类型,则使用重载分辨率确定要应用于这些操作数的转换(如果有)([over。 match.oper],[over.built])。如果重载解析失败,则程序格式错误。否则,将应用由此确定的转换,并在本小节的其余部分中使用转换后的操作数代替原始操作数。

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

请注意,重载解析失败,因为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(); 
      ^ ~~~   ~~~