[英]Ternary operator gives unexpected results in return statement
I'm getting very weird results from ternary operator that should return reference to member object of a linked list. 我从三元运算符得到非常奇怪的结果,应该返回对链表的成员对象的引用。 I have member function in my database object like this:
我在我的数据库对象中有成员函数,如下所示:
Month& GetLastMonth() { return months_.Size() > 0 ? months_.Last() : Month(); }
I call this function 2 times in code: right after loading DB to get info, and when changing some parameters of month and pushing a button. 我在代码中调用了这个函数2次:在加载DB以获取信息后,以及更改月份的某些参数并按下按钮时。
First time I write it to const reference, no big deal here. 我第一次把它写成const参考,这里没什么大不了的。 But second time I need non-const reference to recalculate month (so it will change in DB too).
但第二次我需要非const引用来重新计算月份(因此它也会在DB中发生变化)。
But instead of expected results, some black magic happens. 但不是预期的结果,一些黑魔法发生。 Every time I call
GetLastMonth()
function it returns a reference with different address. 每次调用
GetLastMonth()
函数时,它都会返回一个具有不同地址的引用。 So, after DB loads - its 1 address, recalculating month - its 2nd address and right after saving to file its 3rd address. 所以,在DB加载后 - 它的1个地址,重新计算月份 - 它的第2个地址,并在保存到第3个地址之后立即加载。 Of course, because of this, my changes after recalculating month are not saved to file.
当然,因此,我重新计算月份后的更改不会保存到文件中。
Now, size of months_
are always 1 (for testing purposes). 现在,
months_
大小始终为1(用于测试目的)。 Also it's linked list, so Month can never reallocate. 它也是链表,因此Month永远不会重新分配。 I've tested it, and it never calls
Month()
, so seems like ternary operator is working fine. 我测试了它,它从不调用
Month()
,所以看起来三元运算符工作正常。
Calling it like this, gives same result: 像这样调用它会得到相同的结果:
Month& GetLastMonth() { return months_.Size() ? months_.Last() : Month(); }
Howerver if I call it without ternary: 如果我在没有三元的情况下称它为Howerver:
Month& GetLastMonth() { return months_.Last(); }
Or with proper if()
: 或者使用正确的
if()
:
Month& GetLastMonth()
{
if(months_.Size() > 0)
{
return months_.Last();
}
return Month();
}
It works as expected and returns reference with same address all 3 times. 它按预期工作,并返回具有相同地址的引用3次。 I was thinking about this obscure thing for about 2 days, but still can't find any reasoning behind this.
我在考虑这个不起眼的事情大约2天,但仍然找不到任何理由。
Edit: Related question: Return type of '?:' (ternary conditional operator) 编辑:相关问题: 返回类型'?:'(三元条件运算符)
The ternary operator finds a common type and value category of both operands, and this doesn't happen for the two other cases, which is why it works there. 三元运算符找到两个操作数的公共类型和值类别,对于其他两种情况,这不会发生,这就是它在那里工作的原因。
months_.Last()
and Month()
both have type Month
, so everything is fine there. months_.Last()
和Month()
都有类型Month
,所以一切都很好。 But now, let's examine the value categories. 但现在,让我们来看看价值类别。
months_.Last()
is an lvalue, while Month()
is a prvalue! months_.Last()
是一个左值,而Month()
是一个prvalue! So, the common value category here is a prvalue, and both operands get converted to a prvalue. 因此,这里的公共值类别是prvalue,并且两个操作数都转换为prvalue。 Which means that you get a new
Month
from months_.Last()
every time (from the copy)! 这意味着你得到一个新的
Month
从months_.Last()
从副本)每一次!
Note again however, that this is a MS specific extension. 但请注意,这是MS特定的扩展。 Without that extension, the code would be invalid, as you would try to bind the prvalue returned by the conditional operator to a non-const lvalue reference.
如果没有该扩展,代码将无效,因为您将尝试将条件运算符返回的prvalue绑定到非const左值引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.