10

我有这个代码(简化版):

const int& function( const int& param )
{
     return param;
}

const int& reference = function( 10 );
//use reference

我不能完全确定 C++03 标准 $12.2/5 措辞的程度

引用绑定到的临时对象或作为临时对象绑定的子对象的完整对象的临时对象在引用的生命周期内持续存在...

在这里适用。

reference上面代码中的变量是有效的还是悬空的?调用代码中的引用会延长作为参数传递的临时变量的生命周期吗?

4

4 回答 4

12

完整表达式是不是另一个表达式的子表达式的表达式。在这种情况下,包含调用的完整表达式function( 10 )是赋值表达式:

const int& reference = function( 10 );

为了function使用参数进行调用10,为临时整数对象创建了一个临时 const-reference 对象10。临时整数和临时 const-reference 的生命周期通过赋值扩展,因此尽管赋值表达式有效,但尝试使用所引用的整数reference是未定义的行为,因为reference不再引用活动对象。

我认为 C++11 标准澄清了这种情况:

引用绑定到的临时对象或作为引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在,但以下情况除外:

...

— 在函数调用 (5.2.2) 中对引用参数的临时绑定一直持续到包含调用的完整表达式完成为止。

“引用绑定到的临时......在引用的生命周期内持续存在”。在这种情况下,引用的生命周期在赋值表达式的末尾结束,临时整数的生命周期也是如此。

于 2012-04-17T15:17:11.143 回答
2

这将编译,但您最终会得到一个悬空引用。param返回后被释放function

  1. 函数是通过引用临时的匿名对象来调用的
  2. 函数返回引用
  3. 现在该函数已返回临时参数已释放
  4. 由于对象被破坏,引用现在悬空

如果您将其设为非常量,那么它就不会编译,因为您无法将非常量引用传递给匿名对象。

于 2012-04-17T11:55:27.077 回答
2

从 C++11 的观点来看,函数返回的引用不是临时的:

12.12.1 类类型的临时对象在各种上下文中创建:将引用绑定到纯右值 (8.5.3)、返回纯右值 (6.6.3)、创建纯右值的转换 (4.1、5.2.9、5.2.11 , 5.4)、抛出异常 (15.1)、进入处理程序 (15.3) 以及在某些初始化中 (8.5)。

返回引用的函数不会返回纯右值(“纯右值”),因此它不是临时的。这似乎很自然:编译器无法管理引用对象的生命周期,这是程序员的责任

因此,编译器不为 const int& 引用提供任何提升时间保证,因为它不受临时限制。

于 2012-04-17T14:51:43.553 回答
1

这部分很重要

引用绑定的临时对象

在这种情况下,参数绑定到临时的,并在调用后被销毁。

您不能通过传递引用来进一步延长生命周期。

于 2012-04-17T11:55:56.903 回答