另一个c++临时生命周期混淆
Another c++ temporary lifetime confusion
在下面的代码片段中…在ToXML::s_
成员变量中存储Quote::toXML
返回的临时字符串的引用是否安全,至少只要它仅与<<
操作符一起使用?即子表达式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;
}
是的,它是安全的。
从[class.temp]:在两种上下文中,临时变量在与完整表达式末尾不同的位置被销毁。[…]
第二个上下文是当引用绑定到临时对象时引用所指向的临时对象绑定的或临时的,它是引用被绑定到的子对象的完整对象在引用的生命周期内,除了:
—在函数调用(5.2.2)中绑定到引用形参的临时对象将一直持续到函数调用完成
我们在那个要点上。临时对象被绑定到一个引用形参(s
),并一直存在,直到包含调用的完整表达式完成为止。也就是说,它一直持续到
std::cout << ToXML("quote", q.toXML()) << std::endl;
// --- here ---------------------------------------^
由于它在整个使用过程中持续使用,因此是完全安全的。但是,一旦您执行如下操作:
ToXML x("quote", q.toXML());
你被悬空引用困住了,所以我会谨慎地使用这个模式。
相关文章:
- 如何在共享库的整个生命周期内存储数据
- 如何理解句子的生命周期始于对e的评估
- 它解决了什么问题,对于非真空初始化,生命周期在初始化之前就开始了
- Go/C++gRPC客户端通道和存根生命周期
- 如何将"this"的生命周期移动到C++中的另一个对象中?
- 是否可以通过使用移动/交换 c++11 来延长返回的临时变量的生命周期
- 使用对象的生命周期作为设置器的安全性
- 临时人员的生命周期传递给函数
- 我想知道在构造函数中初始化变量时的生命周期
- Lua 用户数据生命周期管理
- 如何使用 epoll(void* event.data.ptr) 管理 Connection 的生命周期
- C++引用的生命周期
- 在堆栈上有一个对象,而不是在函数的整个生命周期内
- 在 Boost ASIO 服务器中处理生命周期
- C++ lambda 生命周期
- 使用互斥锁跟踪另一个应用的生命周期
- QSharedPointer 或 std::shared_ptr 的生命周期
- 来自async_resolve的 boost::asio::ip::tcp::resolver::iterator 的生命周期是多久?
- 如何调整属于类的唯一指针的字符数组的大小.它必须在程序的整个生命周期中保持活力
- 延长 std::tuple<int&,int> 的生命周期,方法是将其分配给 const std::tuple<int, int>&