[英]Another c++ temporary lifetime confusion
在下面的代码片段中...在ToXML::s_
成员变量中存储对Quote::toXML
返回的临时字符串的引用是否安全,至少只要它仅与<<
运算符一起使用? 即是子表达式q.toXML
的结果,直到下一个;
?
什么是这里的完整表达式 wrt 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;
}
是的,这是安全的。
来自 [class.temp]:
在两种情况下,临时对象在与完整表达式结束不同的点被销毁。 [...]
第二个上下文是当引用绑定到临时对象时。117 引用绑定到的临时对象或作为引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:
— 在函数调用 (5.2.2) 中绑定到引用参数的临时对象一直存在,直到包含调用的完整表达式完成。
我们在那个要点。 临时对象绑定到引用参数 ( s
) 并持续存在,直到包含调用的完整表达式完成。 也就是说,它一直持续到
std::cout << ToXML("quote", q.toXML()) << std::endl;
// --- here ---------------------------------------^
由于它在整个使用过程中持续,因此非常安全。 但是,一旦您执行以下操作:
ToXML x("quote", q.toXML());
你被一个悬空的引用困住了,所以我会谨慎地使用这个模式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.