2014-11-07 74 views
11

如果我正确理解临时对象的生命周期规则,则此代码应该是安全的,因为make_string()中的临时对象stringstream的生存期会持续到完整表达式的结尾。我不是100%自信的,虽然这里没有一个微妙的问题,任何人都可以确认这种使用模式是否安全?它似乎在叮当和gcc工作正常。C++临时对象的生命周期 - 是否安全?

#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"); 
} 
+3

在我看来,它应该没问题。 – 2014-11-07 03:12:01

+0

从技术上讲,没关系,但我相信你会发现效率很低。考虑使用'operator <<'定义一个字符串生成器。 – 2014-11-07 03:23:02

+0

@ Cheersandhth.-Alf取决于编译器内联程度如何。 – cdhowie 2014-11-07 03:23:45

回答

7

的标准的相关部分是在§12.2

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

除了:

12.2.4)有在其中的临时被在不同的点比全表达式的结尾破坏两个上下文。第一个上下文是当调用默认构造来初始化数组的元素时。 ... [不适用]

12.2.5)第二个上下文是引用绑定到临时的时候。临时到该参考结合或临时即其上结合的参考持续基准的寿命除了一个子对象的完整的对象:

  • ...

  • 甲临时绑定到函数调用中的引用参数(5.2.2)直到完成包含调用的完整表达式。

所以你去。临时stringstream{}被绑定到函数调用中的引用,所以它一直存在直到表达式的完成。这是安全的。

+0

谢谢,那看起来非常明确:) – mattnewport 2014-11-07 03:42:49