延长临时工的寿命 [英] prolonging the lifetime of temporaries

查看:19
本文介绍了延长临时工的寿命的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

允许这样做的设计原理是什么

What is the design rationale behind allowing this

const Foo& a = function_returning_Foo_by_value();

但不是这个

Foo& a = function_returning_Foo_by_value();

?

第二行可能会出错(第一行不会出错)?

What could possible go wrong in the second line (which would not already go wrong in the first line)?

推荐答案

我会回答你的问题......反过来.

I'll answer your question... the other way around.

为什么他们允许 Foo const&foo = fooByValue(); 以 ?

Why did they allowed Foo const& foo = fooByValue(); to begin with ?

它让生活(在某种程度上)更轻松,但会在各处引入潜在的未定义行为.

It makes life (somewhat) easier, but introduces potential undefined behavior all over the place.

Foo const& fooByReference()
{
  return fooByValue(); // error: returning a reference to a temporary
}

这显然是错误的,编译器确实会尽职尽责地报告.根据 Tomalak 的评论:标准没有强制要求,但好的编译器应该报告它.Clang、gcc 和 MSVC 都可以.我认为 Comeau 和 icc 也会.

This is obviously wrong, and indeed the compiler will dutifully report it. As per Tomalak's comment: it is not mandated by the standard, but good compilers should report it. Clang, gcc and MSVC do. I think that Comeau and icc would too.

Foo const& fooByIndirectReference()
{
  Foo const& foo = fooByValue(); // OK, you're allowed to bind a temporary
  return foo;                    // Generally accepted
}

这是错误的,但更微妙.问题是临时变量的生命周期与 foo 的生命周期绑定,它在函数结束时超出范围.foo副本被传递给调用者,这个副本指向以太.

This is wrong, but is more subtle. The problem is that the lifetime of the temporary is bound to the lifetime of foo, which goes out of scope at the end of the function. A copy of foo is passed to the caller, and this copy points into the ether.

我在 Clang 上提出了错误,Argyris 能够诊断出这个案例(真的很赞:p).

I raised the bug on Clang, and Argyris was able to diagnose this case (kudos really :p).

Foo const& fooForwarder(Foo const&); // out of line implementation which forwards
                                     // the argument

Foo const& fooByVeryIndirectReference()
{
  return fooForwarder(fooByValue());
}

fooByValue 创建的临时对象绑定到 fooForwarder 参数的生命周期,它尽职尽责地提供一个副本(引用的),副本返回给调用者,即使它现在指向以太.

The temporary created by fooByValue is bound to the lifetime of the argument of fooForwarder, which dutifully provide a copy (of the reference), copy that is returned to the caller, even though it now points into the ether.

这里的问题是 fooForwarder 的实现完全符合标准,但它在调用者中创建了未定义的行为.

The issue here is that fooForwarder's implementation is perfectly fine wrt the standard, and yet it creates undefined behavior in its caller.

尽管如此,令人生畏的事实是,要对此进行诊断需要了解 fooForwarder 的实现,而这对于编译器来说是遥不可及的.

The daunting fact though, is that diagnosing this requires knowing about the implementation of fooForwarder, which is out of reach for the compiler.

我能理解的唯一解决方案(除了 WPA)是运行时解决方案:每当临时对象绑定到引用时,您需要确保返回的引用不共享相同的地址......然后是什么?断言 ?引发异常?而且由于它只是一个运行时解决方案,显然不能令人满意.

The only solution I can fathom (apart from WPA) is a runtime solution: whenever a temporary is bounded to a reference, then you need to make sure that the returned reference does not share the same address... and then what ? assert ? raise an exception ? And since it's only a runtime solution, it is clearly not satisfactory.

将临时对象绑定到引用的想法很脆弱.

这篇关于延长临时工的寿命的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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