C++ - 临时变量及其生命周期

6
这个问题可以视为对以下问题的跟进:C++临时变量生命周期Qt容器支持类似流的初始化语法。现在,当我编写以下代码时,我的QVector在赋值后立即被销毁,引用成为悬空引用。
const QVector<QString>& v = QVector<QString>() << "X" << "Y" << "Z";

对应的 operator<< 的实现方式如下:

inline QVector<T> &operator<< (const T &t)
{ append(t); return *this; }

据我所知,10.4.10 临时对象规定临时对象的生命周期将被延长以匹配相应的const引用的生命周期。
然而,在这种情况下,临时对象QVector<QString>() 会更早地被销毁。 我猜这可能是因为最后一次操作返回了QVector<QString>&,并且不应该知道临时QVector<QString>的生命周期,但这个解释并不严谨,可能是错误的。 那么,为什么会发生这种情况呢?

3
我猜这可能是因为... 你的大致答案是正确的,但技术上的解释是一个 rvalue 正在转换成一个 lvalue。 - ildjarn
我认为temporary绑定到operator <<返回的引用,但在表达式结束时它被销毁。标准只保证将temporary绑定到const ref的生命周期,而不保证与其绑定的temporary's references的生命周期。 - Ramadheer Singh
我知道你的问题满足了学术好奇心,但实际上,你可以通过这种方式使 v 不是一个引用:const QVector<QString> v = QVector<QString>() << "X" << "Y" << "Z"; - Robᵩ
@Robᵩ:这里有一些微妙之处并非纯学术,例如 for (auto foo : QVector<QString>() << "X" << "Y" << "Z") { ... } 无法正常工作。 - ildjarn
1个回答

8

如果临时变量被绑定到const引用,则其生存期将被延长:

const QVector<QString>& v = QVector<QString>();

然而,在您的代码中,您并没有将临时对象绑定到任何东西上面。相反,您调用了一个成员函数(临时对象的),该函数返回一个引用(指向临时对象)。这个函数调用的结果不再是一个临时对象,而只是一个普通的引用。原始的临时对象在它所出现的完整表达式的末尾就过期了,引用v变成了悬垂引用。
(在新的C++中,通过rvalue限定的成员函数,即可以通过删除“<<”运算符的rvalue版本来禁止此类“意外”。)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接