当右值对象作为函数调用的一部分访问其成员时被销毁
When do rvalue objects get destroyed when accessing their members as part of a function call?
我一直在考虑下面这段代码:
PerformConflict(m_dwSession,
CONFLICT_DETECTED,
item.GetConflictedFile().GetUnNormalizedPath().c_str(),
item.GetSuggestedFile().GetUnNormalizedPath().c_str());
-
GetConflictFile()
返回一个对象。 -
GetUnNormalizedPath()
返回std::wstring
-
c_str()
仅返回const wchar_t*
(在本例中为右值std::wstring
的内容)
我的问题是:规范中是否有任何东西保证这段代码是安全的?也就是说,所有的右值对象保证没有被销毁的时候,c_str()是得到一个指针到他们的内容?
这些临时变量将在它们所在的完整表达式结束时销毁。在您的例子中,这是您发布的整个代码片段。
这绝对没问题,只要你只在函数调用中使用const wchar_t*
。如果你把它存储在任何地方,并试图在呼叫退出后访问它,你将被推入UB的深黑洞。
相关标准报价是(强调我的):
N3337 [class.temporary]/3:
当实现引入具有非平凡构造函数(12.1)的类的临时对象时,12.8),它应确保为临时对象调用构造函数。类似地,析构函数应为用非平凡析构函数调用临时函数(12.4)。临时对象在最后一步被销毁在计算(词法上)包含创建它们的点的完整表达式(1.9)时。这是真的即使该求值以抛出异常结束。销毁的值计算和副作用临时对象只与完整表达式相关联,而不与任何特定的子表达式相关联。
如Herb Sutter所示,右值在其出现的表达式末尾被销毁。但是,如果将它们绑定到"对堆栈上const的引用",则它们的生存期将延长到引用的生存期。
基本上,如果你的函数有这样的签名:
PerformConflict(...,
...,
const std::string& str1, //< any rvalue passed here will have the same lifetime as str1
const std::string& str2 //< any rvalue passed here will have the same lifetime as str2
);
您应该能够在PerformConflict()
中操作字符串而不会出现问题。
PS:如果您按值传递参数(即const std::string str1
)
相关文章:
- 这是关于成员访问规则的正确摘要吗
- 为什么我在空指针错误(链表)中获取成员访问权限
- 成员访问是否在空指针上定义C++?
- C++ IDE 不会推断/自动完成对模板类中的 std::array 下标表达式的成员访问
- 为什么类成员数据必须是静态的才能被模板化类的模板化结构成员访问
- 为什么c++允许成员函数定义中实例的私有成员访问
- C/C++ 包含点的宏参数(成员访问运算符)
- 访问说明符(私有/公共/受保护)如何在内部工作(限制成员访问)?
- 如何将超类的受保护成员访问到其派生类. 如果已在派生类中声明了具有相同名称的函数?
- 内部类私有成员访问和封闭的友好性
- 通过 C++ 中的另一个结构成员访问结构
- 具体化 PRVALUES 成员访问的 decltype 行为不正确
- 常量表达式中的静态成员访问
- XVALUE来自类成员访问表达式
- 未经授权的私有类成员访问会产生编译时错误而不是运行时错误?
- 在 c++ 中,为什么 -> 被称为二进制中缀指针成员访问运算符?
- 如何访问模板参数的成员?“成员访问不完整的类型”
- 不明确的可变参数类成员访问
- C 受保护的成员访问
- 将typeID转换为静态成员访问(C )的命名空间