简体   繁体   English

另一个 C++ 临时生命周期混乱

[英]Another c++ temporary lifetime confusion

In the below code snippet... is it safe to store a reference to the temporary string returned by Quote::toXML in ToXML::s_ member variable, at least as long as it is used with the << operator only?在下面的代码片段中...在ToXML::s_成员变量中存储对Quote::toXML返回的临时字符串的引用是否安全,至少只要它仅与<<运算符一起使用? Ie is the result of the sub-expression q.toXML alive until the next ;即是子表达式q.toXML的结果,直到下一个; ? ?

And what is the full expression here wrt the return value of q.toXML .什么是这里的完整表达式 wrt q.toXML的返回值。 The entire std::cout or the call to ToXML constructor ?整个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;
}

Yes, it is safe.是的,这是安全的。

From [class.temp]:来自 [class.temp]:

There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression.在两种情况下,临时对象在与完整表达式结束不同的点被销毁。 [...] [...]

The second context is when a reference is bound to a temporary.117 The temporary to which the reference is bound or the temporary that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference except:第二个上下文是当引用绑定到临时对象时。117 引用绑定到的临时对象或作为引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:
— A temporary object bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call. — 在函数调用 (5.2.2) 中绑定到引用参数的临时对象一直存在,直到包含调用的完整表达式完成。

We're in that bullet point.我们在那个要点。 The temporary object is bound to a reference parameter ( s ) and persists until the completion of the full-expression containing the call.临时对象绑定到引用参数 ( s ) 并持续存在,直到包含调用的完整表达式完成。 That is, it persists until也就是说,它一直持续到

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

Since it lasts throughout its usage, it is perfectly safe.由于它在整个使用过程中持续,因此非常安全。 However, as soon as you do something like:但是,一旦您执行以下操作:

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

you're stuck with a dangling reference, so I would use this pattern sparingly.你被一个悬空的引用困住了,所以我会谨慎地使用这个模式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM