【问题标题】:Another c++ temporary lifetime confusion另一个 c++ 临时生命周期混乱
【发布时间】:2015-09-27 22:55:23
【问题描述】:

在下面的代码 sn-p... 中存储对 Quote::toXML 返回的临时字符串的引用在 ToXML::s_ 成员变量中是否安全,至少只要它与 << 运算符一起使用只要? IE。子表达式q.toXML 的结果是否一直存在到下一个;

这里的完整表达是什么? q.toXML 的返回值。整个std::cout 还是对ToXML 构造函数的调用?

#include <iostream>
#include <string>

struct ToXML
{
    ToXML(char const * const tag, std::string const & s) : tag_(tag), s_(s)
    {
    }

    char const * tag_;
    std::string const & s_;
};

std::ostream & operator << (std::ostream & os, ToXML const & v)
{
    return os << "<" << v.tag_ << ">" << v.s_ << "</" << v.tag_ << ">";
}

struct Quote
{
    std::string toXML() const
    {
        return "<Quote/>";
    }
};

int main()
{
    Quote q;
    std::cout << ToXML("quote", q.toXML()) << std::endl;
    return 0;
}

【问题讨论】:

标签: c++


【解决方案1】:

是的,它是安全的。

来自 [class.temp]:

在两种情况下,临时对象在与完整表达式结尾不同的点被销毁。 [...]

第二个上下文是当一个引用被绑定到一个临时的时。117 引用所在的临时 绑定或作为引用所绑定的子对象的完整对象的临时对象仍然存在 在引用的生命周期内,除了:
— 在函数调用 (5.2.2) 中绑定到引用参数的临时对象将持续存在直到完成 包含调用的完整表达式。

我们就在那个要点上。临时对象绑定到引用参数 (s) 并持续存在,直到包含调用的完整表达式完成为止。也就是说,它一直持续到

std::cout << ToXML("quote", q.toXML()) << std::endl;
// --- here ---------------------------------------^

由于它可以在整个使用过程中持续使用,因此非常安全。但是,只要您执行以下操作:

ToXML x("quote", q.toXML());

你被一个悬空的引用困住了,所以我会谨慎地使用这个模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-19
    • 2021-05-17
    相关资源
    最近更新 更多