当作为函数调用的一部分访问其成员时,rvalue对象何时被销毁?

时间:2015-10-16 09:25:22

标签: c++

我一直在考虑以下代码:

    PerformConflict(m_dwSession, 
        CONFLICT_DETECTED, 
        item.GetConflictedFile().GetUnNormalizedPath().c_str(), 
        item.GetSuggestedFile().GetUnNormalizedPath().c_str());
  • GetConflictFile()返回一个对象。
  • GetUnNormalizedPath() 返回std::wstring
  • c_str()只返回const wchar_t*(在这种情况下为rvalue std::wstring的内容)

我的问题是:规范中的任何内容都保证此代码是安全的吗?即是否所有的rvalue对象都保证在c_str()获取指向其内容的指针时不会被破坏?

2 个答案:

答案 0 :(得分:5)

那些临时演员将在他们出现的完整表达结束时被销毁。在你的情况下,这就是你发布的整个片段。

只要您 在该函数调用中使用const wchar_t*,这将是绝对正常的。如果你将它存放在任何地方,并在呼叫退出后尝试访问它,你将被推到UB的深黑洞。

相关标准引用是(强调我的):

  

N3337 [class.temporary]/3:   当一个实现引入一个具有非平凡构造函数的类的临时对象时(12.1,   12.8),它应确保为临时对象调用构造函数。同样,析构函数应该是   用非平凡的析构函数(12.4)调用临时函数。 临时对象作为最后一步被销毁   在评估全表达式(1.9)时(词法上)包含创建它们的点。这是真的   即使该评估以抛出异常结束。价值计算和破坏的副作用   临时对象仅与完整表达式相关联,而不与任何特定子表达式相关联。

答案 1 :(得分:1)

作为illustrated by Herb Sutter,rvalues在它们出现的表达式的末尾被销毁。但是,如果将它们绑定到"对堆栈上的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

,也可以解决问题