通过引用传递和返回参数时的整体提升?
我正在阅读一些有关重载解析的内容,发现了一些让我困扰的内容...在以下代码中:
int const& MaxValue(int const& a, int const& b)
{
return a > b ? a : b;
}
void SomeFunction()
{
short aShort1 = 3;
short aShort2 = 1;
int const & r2 = MaxValue(aShort1, aShort2); // integral promotion
//is it safe to pass r2 around before function SomeFunction completes
// CallSomeOtherFunctionThatCallsSomethingElse(r2);
}
我的理解是创建了两个临时 int,并将它们分配在属于 SomeFunction 的堆栈上。 因此,当 MaxValue 返回时,r2 引用这些临时变量之一(在本例中为保存值 3 的变量)。 因此,传递 r2 应该是安全的。
问题是,如果我的理解没问题,这是标准行为吗(请验证)?如果没有,请解释上面代码中发生了什么。
非常感谢
I'm reading something about overload resolution and I found something that bothers me...In the following code:
int const& MaxValue(int const& a, int const& b)
{
return a > b ? a : b;
}
void SomeFunction()
{
short aShort1 = 3;
short aShort2 = 1;
int const & r2 = MaxValue(aShort1, aShort2); // integral promotion
//is it safe to pass r2 around before function SomeFunction completes
// CallSomeOtherFunctionThatCallsSomethingElse(r2);
}
My understanding is that two temporary int's are created and they're allocated on the stack belonging to SomeFunction.
So when MaxValue returns, r2 referencing to one of those temp variables (in this case, the one that holds value 3).
Thus, is should be safe to pass r2 around.
The question is, if my understanding is fine, is this a standard behavior (please verify)? If not, please explain what is happening in above code.
Many Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
欢迎了解为什么隐式转换很糟糕。您现在拥有对已被销毁的临时对象的引用。希望你不想用它做任何事。
Welcome to why implicit casts suck. You now have a reference to a temporary, which has been destroyed. Hope you didn't want to do anything with it.
是的,您的理解很好,这是标准行为。
除了这个:
我不明白。
// 编辑
您应该在此处使用指针而不是引用来实现相同的目标,但不会出现问题。仅在函数内使用通过 const 引用传递的参数地址才可以,因为它可能指向对象的本地副本。
Yes, your understanding is fine and this is standard behaviour.
Except this:
which I do not understand.
// EDIT
You should use pointers instead of references here to achieve the same but without the problem. Using address of an argument passed by const reference is OK only within the function because it may point to local copy of an object.
简短的回答:这是不安全的。
该标准保证临时变量可以绑定到常量引用,在这种情况下,临时变量的生命周期将扩展为绑定引用的生命周期。您的特定情况下的问题是实际绑定临时的引用是什么。
当您调用
MaxValue( s1, s2 )
时,会创建两个 int 类型的临时变量,并将其绑定到a
和b
中的参数参数a
和b
代码>最大值。这意味着这些临时对象的寿命延长到功能完成为止。现在,在函数的 return 语句中,您将对临时变量之一进行第二次引用,并且第二次引用不会延长生命周期。 r2 不会进一步延长对象的生命周期,并且您有一个悬空引用。请注意,由于单独编译,编译器不可能从
MaxValue
外部知道返回的引用是对参数之一还是对非临时的完全不同的对象:因此它不可能猜测是否需要延长任何或哪一个临时生命周期。
附带说明一下,对于小对象(例如所有整数类型),通过引用传递实际上可能比通过值传递更糟糕。此外,已经有一个 std::max 模板实际实现了此功能。
Short answer: it is unsafe.
The standard guarantees that a temporary variable can be bound to a constant reference in which case the lifespan of the temporary expands to the lifetime of the bound reference. The problem in your particular case is what reference is actually binding the temporary.
When you call
MaxValue( s1, s2 )
, two temporary variables of type int are created and bound to the parameter argumentsa
andb
inMaxValue
. This means that the lifespan of those temporaries is extended to the completion of the function. Now, in the return statement of your function you are taking a second reference to one of the temporaries and that second reference will not extend the lifetime.r2
will not further extend the lifetime of the object, and you have a dangling reference.Note that due to the separate compilation, the compiler cannot possibly know from outside of
MaxValue
whether the returned reference is to one of the arguments or to a completely different object that is not a temporary:So it cannot possibly guess whether any or which of the temporaries lifetime needs to be extended.
As a side note, for small objects (such as all integer types) passing by reference may be actually worse than passing by value. Also there is already an
std::max
template that actually implements this functionality.对于简单类型,您应该返回并按值传递。
You should return and pass by value for simple types.