【发布时间】:2013-12-12 15:05:02
【问题描述】:
在 C++ 中,可以通过将临时值绑定到引用来延长其生命周期:
Foo make_foo();
{
Foo const & r1 = make_foo();
Foo && r2 = make_foo();
// ...
} // both objects are destroyed here
为什么允许这样做?这解决了什么问题?
我在 Design and Evolution 中找不到对此的解释(例如 6.3.2:临时生命周期)。我也找不到任何关于此的先前问题(this one 最接近)。
此功能有些不直观,并且具有微妙的故障模式。例如:
Foo const & id(Foo const & x) { return x; } // looks like a fine function...
Foo const & r3 = id(make_foo()); // ... but causes a terrible error!
为什么可以如此轻易地、默默地滥用语言的一部分?
更新:这一点可能足够微妙,需要澄清一下:我不反对使用“引用绑定到临时对象”的规则。这一切都很好,并且允许我们在绑定到引用时使用隐式转换。我要问的是为什么临时的 lifetime 会受到影响。说白了,我可以声称现有的“直到完整表达式结束的生命周期”规则已经涵盖了使用临时参数调用函数的常见用例。
【问题讨论】:
-
我假设如果你有一个返回
std::string的函数和一个返回std::string const&的函数,你不必关心返回的是哪个函数;你可以写std::string const& x = foo()。 -
注意:一个非常有趣的例子:
long const& l = std::min<long>(0, 1);是不安全的,因为存在从int到long const&和min的隐式转换,然后返回此引用。 叹息 -
@MatthieuM.: 是的,准确地说:-)
-
@DavidRodríguez-dribeas 这也符合我们的政策。我们有几个程序员经常这样做;我们只是逐渐摆脱它。 (除了所有其他潜在问题之外,它实际上会导致代码稍微变慢,至少在某些构建中,因为额外的间接性。)
-
@DavidRodríguez-dribeas 条件多态性是延长寿命有意义的一种情况。但是尽我所能,我无法想出一个相关的初始化表达式。可能是
Base const& obj = cond ? Base() : Derived();之类的东西。但是一旦它变成cond ? Derived1() : Derived2()(几乎总是这样),你就需要一个static_cast<Base&>,并且用static_cast<Base&>的结果初始化一个引用并不会延长生命周期演员的对象。
标签: c++ language-design