如果我正确理解临时对象生命周期的规则,那么这段代码应该是安全的,因为临时对象的生命周期stringstream
in make_string()
持续到完整表达式结束。我不是 100% 确信这里没有一个微妙的问题,但有人可以确认这种使用模式是否安全吗?它似乎在 clang 和gcc http://ideone.com/C0uMc3.
#include <iomanip>
#include <iostream>
#include <sstream>
using namespace std;
ostringstream& make_string_impl(ostringstream&& s) { return s; }
template<typename T, typename... Ts>
ostringstream& make_string_impl(ostringstream&& s, T&& t, Ts&&... ts) {
s << t;
return make_string_impl(std::move(s), std::forward<Ts>(ts)...);
}
template<typename... Ts>
string make_string(Ts&&... ts) {
return make_string_impl(ostringstream{}, std::forward<Ts>(ts)...).str();
}
int main() {
cout << make_string("Hello, ", 5, " World!", '\n', 10.0, "\n0x", hex, 15, "\n");
}
标准的相关部分位于§12.2
:
12.2.3) 最后一步销毁临时对象
在评估完整表达式(1.9)时,(从词法上)包含它们被创建的点。
Except:
12.2.4) 在两种情况下,临时变量会在与完整表达式末尾不同的点被销毁。第一个上下文是调用默认构造来初始化数组的元素时。 ... [不适用]
12.2.5) 第二个上下文是当引用绑定到临时对象时。引用绑定到的临时对象或引用绑定到的子对象的完整对象的临时对象在引用的生命周期内持续存在,但以下情况除外:
所以就这样吧。临时的stringstream{}
绑定到函数调用中的引用,因此它会持续存在,直到表达式完成。这是安全的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)