我一直在考虑以下代码:
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()获取指向其内容的指针时不会被破坏?
答案 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
)