临时C++的生命周期 - 这样安全吗?

mat*_*ort 11 c++ c++11

如果我理解的临时的寿命正确的规则,因为临时的寿命这段代码应该是安全的stringstreammake_string()持续,直到完全表达的结束.我不是100%有信心这里没有一个微妙的问题,任何人都可以确认这种使用模式是否安全吗?它似乎在clang和gcc中运行良好.

#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");
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 7

该标准的相关部分是§12.2:

12.2.3)临时对象作为评估全表达式(1.9)的最后一步被销毁,该表达式(词法上)包含创建它们的点.

除了:

12.2.4)有两种情况下,临时表在与完整表达结束时不同的点被销毁.第一个上下文是调用默认构造来初始化数组的元素....... [ 不适用 ]

12.2.5)第二个上下文是指引用绑定到临时的.绑定引用的临时对象或绑定引用的子对象的完整对象的临时对象在引用的生命周期内持续存在,除了:

  • ...

  • 函数调用(5.2.2)中的引用参数的临时绑定将持续到包含该调用的完整表达式完成为止.

你去吧 临时stringstream{}绑定到函数调用中的引用,因此它将持续到表达式完成.这很安全.