为什么const引用不能延长通过函数传递的临时对象的寿命? [英] Why doesn't a const reference extend the life of a temporary object passed via a function?

查看:96
本文介绍了为什么const引用不能延长通过函数传递的临时对象的寿命?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的简单示例中,为什么不能将ref2绑定到min(x,y+1)的结果?

In the following simple example, why can't ref2 be bound to the result of min(x,y+1)?

#include <cstdio>
template< typename T > const T& min(const T& a, const T& b){ return a < b ? a : b ; }

int main(){
      int x = 10, y = 2;
      const int& ref = min(x,y); //OK
      const int& ref2 = min(x,y+1); //NOT OK, WHY?
      return ref2; // Compiles to return 0
}

实时示例-产生:

main:
  xor eax, eax
  ret

我认为,下面的示例更好地描述了一种情况.

Below example better described a situation, I think.

#include <stdio.h>


template< typename T >
constexpr T const& min( T const& a, T const& b ) { return a < b ? a : b ; }



constexpr int x = 10;
constexpr int y = 2;

constexpr int const& ref = min(x,y);  // OK

constexpr int const& ref2 = min(x,y+1); // Compiler Error

int main()
{
      return 0;
}

实时示例产生:

<source>:14:38: error: '<anonymous>' is not a constant expression

 constexpr int const& ref2 = min(x,y+1);

                                      ^

Compiler returned: 1

推荐答案

这是设计使然.简而言之,只有与 直接绑定的命名引用会延长其寿命.

It's by design. In a nutshell, only the named reference to which the temporary is bound directly will extend its lifetime.

[class.temporary]

5在三种情况下, 与完整表达的结束点不同. [...]

5 There are three contexts in which temporaries are destroyed at a different point than the end of the full-expression. [...]

6第三种情况是引用绑定到临时项时. 引用绑定到的临时对象或引用的临时对象 引用绑定到的子对象的完整对象 在参考的有效期内持续存在,除了:

6 The third context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:

  • 绑定到函数调用中的参考参数的临时对象将持续存在,直到包含以下内容的完整表达式完成 电话.
  • 在函数return语句中,临时绑定到返回值的生存期不会延长;临时被毁 在return语句中的完整表达式的末尾.
  • [...]
  • A temporary object bound to a reference parameter in a function call persists until the completion of the full-expression containing the call.
  • The lifetime of a temporary bound to the returned value in a function return statement is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
  • [...]

您没有直接绑定到ref2,甚至可以通过return语句将其传递.该标准明确表示不会延长使用寿命.在某种程度上使某些优化成为可能.但是最终,因为很难理解在引用传入和传出函数时应该扩展哪个临时对象.

You didn't bind directly to ref2, and you even pass it via a return statement. The standard explicitly says it won't extend the lifetime. In part to make certain optimizations possible. But ultimately, because keeping track of which temporary should be extended when a reference is passed in and out of functions is intractable in general.

由于编译器会在程序没有任何未定义行为的前提下进行积极的优化,因此您可能会看到这种情况.未定义在其生存期之外访问值的操作,这是return ref2; 所要做的,并且由于该行为是未定义的,因此简单地返回零便是有效的行为.编译器不会破坏合同.

Since compilers may optimize aggressively on the assumption that your program exhibits no undefined behavior, you see a possible manifestation of that. Accessing a value outside its lifetime is undefined, this is what return ref2; does, and since the behavior is undefined, simply returning zero is a valid behavior to exhibit. No contract is broken by the compiler.

这篇关于为什么const引用不能延长通过函数传递的临时对象的寿命?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆