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

Pra*_*tic 17 c++ standards

为什么C++委员会决定const引用应该延长temporaries的生命周期?

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

GotW#88:"最重要的const"的候选人

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

(另一种选择是临时的寿命不会被任何参考文献扩展.)


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

Ric*_*ges 17

它是在1993年提出的.它的目的是在引用时消除对临时工具的不一致处理.

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

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

  • 哇,那时我才10岁。知道原因确实很有趣。+1 用于论文链接。 (2认同)
  • @skypjack 1993年是我第一次放弃编程的那一年,因为我想要一些冒险...... (2认同)

Leo*_*eon 5

您不是在质疑为什么允许常量引用绑定到临时文件,而只是质疑为什么它们会延长这些临时文件的生命周期。

考虑这个代码:

struct A
{
    void foo() const;
};

A bar();

const A& a = bar();

a.foo();               // (1)
Run Code Online (Sandbox Code Playgroud)

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


编辑(解决OP 的评论):

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

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

B bar();

const B& b = bar();

b.foo();               // (1)
Run Code Online (Sandbox Code Playgroud)

此示例与前一个示例的唯一区别在于它B::foo()是虚拟的。现在,如果我们决定引入一个新类D作为 的子类B并将bar()from的返回类型更改BD呢?

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.
Run Code Online (Sandbox Code Playgroud)

因此,将常量引用绑定到临时对象简化了对按值返回的对象的动态多态性的利用。