'?:'的返回类型(三元条件运算符)

为什么第一个返回一个引用?

int x = 1;
int y = 2;
(x > y ? x : y) = 100;

而第二个不?

int x = 1;
long y = 2;
(x > y ? x : y) = 100;

实际上,第二个根本没有编译 - “不是左值任务”。



三元?:表达式的类型是其第二个和第三个参数的常见类型。 如果两种类型都相同,则返回参考。 如果他们可以相互转换,一个会被选中,另一个会被转换(在这种情况下被提升)。 由于您不能将左值引用返回到临时(转换/升级的变量),因此其类型是值类型。


它不能返回左值,因为它必须隐含地提升x的类型以匹配y的类型(因为:两边都不是相同类型),并且必须创建一个临时值。


标准说什么? (n1905)

表达式5.17赋值和复合赋值操作符

5.17 / 3

如果第二个和第三个操作数具有不同的类型,并且具有(可能是cv-qualified)类类型,则会尝试将每个操作数转换为另一个操作数的类型。 用于确定类型T1的操作数表达式E1是否可以被转换以匹配类型T2的操作数表达式E2的过程定义如下:

- 如果E2是一个左值:如果E1可以被隐式转换(第4章)为类型“T2的引用”,则E1可以被转换为匹配E2,受限于在转换中引用必须直接绑定(8.5.3 )到E1。

- 如果E2是一个右值,或者上面的转换不能完成:

- 如果E1和E2具有类类型,并且基础类类型相同或一个是另一个类的基类:如果T2的类与类型相同,或者基类为,T1的等级和T2的cv资格与T1的cv资格相同,或者更高的cv资格。 如果应用了转换,则E1被改变为仍然引用原始源类对象(或其适当的子对象)的类型T2的右值。 [注意:也就是说,不做任何复制。 通过从E1中复制初始化T2类型的临时文件并将该临时文件用作转换后的操作数来结束注释]。

否则(即,如果E1或E2具有非类别类型,或者它们都具有类别类型,但基础类别不是相同的或者是另一类别的基类别):如果E1可以转换E1以匹配E2如果E2被转换为右值(或者它所具有的类型,如果E2是右值),则隐式转换为表达式E2将具有的类型。

使用该过程,确定是否可以将第二操作数转换为匹配第三操作数,以及是否可以转换第三操作数以匹配第二操作数。 如果两者都可以转换,或者可以转换,但转换不明确,则该程序不合格。 如果两者都不可转换,则操作数保持不变,并按照下面的描述执行进一步的检查。 如果只有一次转换是可能的,则该转换将应用于所选操作数,转换后的操作数将用于替代本节其余部分的原始操作数。


5.17 / 4

如果第二和第三操作数是左值并且具有相同类型,则结果是该类型并且是左值,并且如果第二或第三操作数是位域,或者如果两者都是位域,则它是位域,领域。


5.17 / 5

否则,结果是一个右值。 如果第二个和第三个操作数不具有相同的类型,并且具有(可能为cv-qualified)类类型,则使用重载决策来确定要应用于操作数的转换(如果有的话)(13.3.1.2,13.6) 。 如果重载解决失败,则该程序不合格。 否则,应用这样确定的转换,并使用转换的操作数代替本节其余部分的原始操作数。

链接地址: http://www.djcxy.com/p/31489.html

上一篇: Return type of '?:' (ternary conditional operator)

下一篇: Tricky ternary operator in Java