为什么const引用会延长rvalues的生命周期?

时间:2016-09-27 07:11:05

标签: c++ standards

为什么C ++委员会决定const引用应该延长临时工作的寿命?

这个事实已经在网上广泛讨论过,包括stackoverflow。解释这种情况的最终资源可能就是GoTW:

GotW #88: A Candidate For the “Most Important const”

此语言功能的基本原理是什么?它知道了吗?

(替代方案是临时的寿命不会被任何参考文献扩展。)

我自己的宠物理论的基本原理是这种行为允许对象隐藏实现细节。使用此规则,成员函数可以在不对客户端代码进行任何更改的情况下,在返回值或const引用与已内部存在的值之间切换。例如,矩阵类可能能够返回行向量和列向量。为了最小化副本,可以返回一个或另一个作为参考,具体取决于实现(行主要与列主要)。无论通过引用返回哪一个都必须通过复制并返回该值来返回(如果返回的向量是连续的)。库编写者可能希望在未来改变实现(行主要与列专业),并防止客户端编写强烈依赖于实现是行主要还是列主要的代码。通过要求客户端接受返回值为const ref,矩阵类可以返回const引用或值,而无需对客户端代码进行任何更改。无论如何,如果原始的理由是已知的,我想知道它。

2 个答案:

答案 0 :(得分:16)

它是在1993年提出的。它的目的是在绑定参考时消除对临时工具的不一致处理。

当时,没有像RVO这样的东西,所以简单地禁止临时绑定到引用就会受到性能影响。

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0345.pdf

答案 1 :(得分:3)

你不是在质疑为什么允许const引用绑定到临时对象,而只是为什么它们会延长那些临时对象的生命周期。

考虑以下代码:

struct A
{
    void foo() const;
};

A bar();

const A& a = bar();

a.foo();               // (1)

如果bar()返回的临时值的生命周期没有延长,那么a的任何使用(由第(1)行示例)都会导致未定义的行为。这会使对temporaries的非参数const引用的绑定完全无用。

编辑(寻址OP's comment):

因此,真正的问题应该是为什么允许const引用变量(不是函数参数)绑定到临时变量。我不知道它的原始理由(Richard Hodges' answer可能是唯一真实的理由),但它为我们提供了一个有用的功能。考虑以下示例:

struct B
{
    virtual void foo() const;
};

B bar();

const B& b = bar();

b.foo();               // (1)

此示例与上一个示例的唯一区别在于B::foo()是虚拟的。现在,如果我们决定引入新类D作为B的子类并将bar()的返回类型从B更改为D,该怎么办?< / p>

struct B
{
    virtual void foo() const;
};

struct D : B
{
    virtual void foo() const;
};

//B bar();
D bar();

const B& b = bar();

b.foo(); // This will call D::foo()

// In the end the temporary bound by b will be correctly destroyed
// using the destructor of D.

因此,对temporaries的绑定const引用简化了对由value返回的对象的动态多态性的优势。