C ++:三元运算符(条件运算符)及其隐式类型转换规则

时间:2015-08-27 13:59:23

标签: c++ types implicit ternary

是否存在三元运算符参数的隐式类型转换规则?

三元运算符始终需要返回相同的类型。此类型仅由第二个和第三个参数(1st ? 2nd : 3rd)确定,因此两个参数都将转换为此类型。这种类型是如何确定的?

更具体地说,我测试了一个例子:

class pointclass
{
    pointclass();

    pointclass( int i );    // (pointclass)(int)
    operator bool() const;  // (bool)(pointclass)
};

我有一个类(pointclass),它允许从intpointclass的隐式转换以及从pointclassbool的隐式转换。

int i;
pointclass p;
bool b;

b ? p : i;  // (bool) ? (int)(bool)(pointclass) : (int)
b ? i : p;  // (bool) ? (int) : (int)(bool)(pointclass)

使用三元运算符,我比较pointclassint。编译器使用从pointclassbool的隐式转换,然后是从boolint的标准转换。无论我是否交换第二和第三个参数,这都已完成。 为什么不将int转换为pointclass

使用比较运算符要简单得多:

p == i;     // (pointclass) == (pointclass)(int)
i == p;     // (int) == (int)(bool)(pointclass)

参数的类型仅由第一个参数决定。

但我不明白三元运算符的类型转换规则。对我来说,这似乎就像使用大多数转换的方式一样。

1 个答案:

答案 0 :(得分:6)

引用MSDN

  

条件表达式具有从右到左的关联性。首先   操作数必须是整数或指针类型。以下规则适用   第二和第三个操作数:

     

如果两个操作数的类型相同,则结果属于该类型。

     

如果两个操作数都是算术类型或枚举类型,则通常的算术转换(在算术转换中涵盖)是   执行以将它们转换为通用类型。

     

如果两个操作数都是指针类型或者如果一个是指针类型而另一个是一个计算结果为0的常量表达式,则指针   执行转换以将它们转换为通用类型。

     

如果两个操作数都是引用类型,则执行引用转换以将它们转换为通用类型。

     

如果两个操作数都是void类型,则常见类型为void。

     

如果两个操作数具有相同的用户定义类型,则常见类型为该类型。

     

如果操作数具有不同的类型且至少有一个操作数具有用户定义的类型,那么语言规则用于   确定常见类型。 (见下面的警告。)

基本上,C ++编译器会查找第二个和第三个操作数的公共类型。如果它能找到它,那就是结果类型。如果找不到,则会导致编译时错误。

如果您想查看标准位置,可以查看规则in working draft for newest standard,5.16(第129页)。

从不将int转换为pointclass - 一般规则是你总是沿着层次结构而不是 - 想象更高级的类层次结构;可能有几种方法可以将这两种类型转换为其他类,但这真的是你想要的吗?而且,确定使用哪个类是不可能的。因此,我们垂头丧气。