为什么第一个返回引用?
int x = 1;
int y = 2;
(x > y ? x : y) = 100;
虽然第二个没有?
int x = 1;
long y = 2;
(x > y ? x : y) = 100;
实际上,第二个根本不编译-“没有左赋值”。
为什么第一个返回引用?
int x = 1;
int y = 2;
(x > y ? x : y) = 100;
虽然第二个没有?
int x = 1;
long y = 2;
(x > y ? x : y) = 100;
实际上,第二个根本不编译-“没有左赋值”。
Answers:
表达式没有返回类型,它们具有一个类型,并且(如最新的C ++标准所知)具有一个值类别。
条件表达式可以是左值或右值。这是其价值类别。(这有点简化,C++11
因为我们有左值,左值和右值。)
用非常广泛和简单的术语来说,一个左值是指内存中的一个对象,而一个右值只是一个不一定要附加到内存中的对象的值。
赋值表达式为对象分配一个值,因此要赋值的对象必须是一个左值。
对于条件表达式(?:
)是一个左值(再次,在广泛的和简单的术语),所述第二和第三操作数必须是左值的相同类型的。这是因为条件表达式的类型和值类别是在编译时确定的,并且无论条件是否为真都必须适当。如果必须将一个操作数转换为其他类型以与另一个匹配,则条件表达式不能为左值,因为此转换的结果将不是左值。
ISO / IEC 14882:2011参考:
3.10 [basic.lval]左值和右值(关于值类别)
5.15 [expr.cond]条件运算符(条件表达式具有什么类型和值类别的规则)
5.17 [expr.ass]赋值和复合赋值运算符(要求赋值的lhs必须是可修改的左值)
an rvalue is just a value that may not necessarily be *attached* to an object in memory.
您能用更简单的术语来解释吗?。另外,你是什么意思type and value *category*
?谢谢
prvalue, xvalue, glvalue
是值类别。
true
,this
,enum
值。这些东西是prvalues(“纯” rvalues),但不存在于内存中。
三元?:
表达式的类型是其第二和第三个参数的常见类型。如果两种类型相同,则会得到一个参考。如果它们彼此可转换,则一个被选择,另一个被转换(在这种情况下被提升)。由于您不能将左值引用返回到临时值(转换/提升的变量),因此其类型为值类型。
它不能返回左值,因为它必须隐式地提升的类型x
以匹配的类型y
(因为的两端:
都不是同一类型),并且它必须创建一个临时值。
表达式5.17赋值和复合赋值运算符
5.17 / 3
如果第二个操作数和第三个操作数具有不同的类型,并且每个操作数都具有(可能是cv限定的)类类型,则尝试将每个操作数转换为另一个操作数的类型。确定是否可以将类型T1的操作数表达式E1转换为匹配类型T2的操作数表达式E2的过程定义如下:
—如果E2是左值:如果可以将E1隐式转换为“对T2的引用”类型,则可以将E1转换为与E2匹配,但要满足以下条件:在转换中,引用必须直接绑定(8.5.3) )到E1。
—如果E2是右值,或者无法完成上述转换:
—如果E1和E2具有类类型,并且基础类类型相同,或者一个是另一类的基类:如果T2的类是与E2相同的类型,则可以将E1转换为匹配E2。 ,T1的类别和T2的cv资格与t1的cv资格相同,或具有比T1的cv资格更大的cv资格。如果应用了转换,则将E1更改为类型T2的右值,该值仍引用原始源类对象(或其适当的子对象)。[ 注意:即不进行复制。通过使用E1复制初始化类型T2的临时对象并将该临时对象用作转换后的操作数,来将其作为结尾。
否则(例如,如果
E1
或E2具有非类类型,或者它们都具有类类型,但基础类既不相同,又不是另一个基类):如果E1可以是E1,则可以将E1转换为匹配E2。如果将E2转换为右值,则隐式转换为表达式E2的类型(如果E2是右值,则隐式转换为该类型)。使用此过程,确定是否可以转换第二操作数以匹配第三操作数,以及是否可以转换第三操作数以匹配第二操作数。如果两者都可以转换,或者一个都可以转换但转换不明确,则说明程序格式错误。如果两个都不能转换,则操作数保持不变,并按如下所述进行进一步检查。如果仅可能进行一次转换,则将该转换应用于所选的操作数,并在本节的其余部分中使用转换后的操作数代替原始操作数。
5.17 / 4
如果第二和第三操作数是左值并且具有相同的类型,则结果是该类型并且是左值,并且如果第二或第三操作数是位字段,或者如果两个都是位-则结果是位字段。领域。
5.17 / 5
否则,结果为右值。如果第二个和第三个操作数不具有相同的类型,并且都具有(可能是cv限定的)类类型,则使用重载分辨率来确定要应用于这些操作数的转换(如果有)(13.3.1.2、13.6) 。如果重载解析失败,则程序格式错误。否则,将应用由此确定的转换,并在本节的其余部分中使用转换后的操作数代替原始操作数。