C ++ stringstream inline

时间:2014-06-30 16:28:32

标签: c++ stl stringstream

我想使用std::stringstream来创建格式化的字符串,但是使用内联类,因此我没有stringstream个局部变量飞来飞去。我的意思是:

#include <iostream>
#include <ostream>
#include <string>
#include <sstream>

int main(int argc, char* argv[])
{
    std::string test = ((std::ostringstream&)
         (std::ostringstream("") << "This is a test: " << 50.1 << "abc")
         ).str();
    std::cout << test << std::endl;
    return 0;
}

这在GCC中编译得很好,但输出如下:

  

&#34; 0x401d0a50.1abc&#34;

所以似乎stringstream将第一个字符串视为指针并输出地址。随后的operator<<工作正常。

我该如何解决这个问题? 谢谢!

2 个答案:

答案 0 :(得分:6)

原因是<<运算符是void const*的成员,但是自由函数将std::ostream&作为char const*的左手参数。你的std::ostringstream( "" )是临时的:你可以在其上调用成员函数(甚至是非const成员函数),但是临时函数不能用于初始化全局函数的非const引用。

编辑:

两点:首先,正如已经指出的那样,g ++确实做到了 想要指定-std=c++11。作为T.C.指出,这是 在§27.7.3.9中指定,它提供了模板重载 所有<<都带有std::istream的右值参考 参数。 第二,经典的工作是 开始表达式std::ostringstream( "" ).flush() <<...flush是一个成员函数(因此可以调用 一个临时的)返回一个std::ostream&(所以一切 其他链条很好);它也没有做任何事情 std::ostringstream

答案 1 :(得分:2)

找到它。 C ++ 11标准特殊情况rvalue流带有额外的模板operator<<重载。 §27.7.3.9标准:

  

Rvalue stream insertion [ostream.rvalue]

template <class charT, class traits, class T>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>&& os, const T& x);
     

效果:os << x

     

返回:os

显然比成员operator<<更好地匹配const void *,因此在C ++ 11模式下通过重载决策选择。在C ++ 98模式下,这个重载不存在(因为没有右值引用),唯一可行的重载是成员operator<<(因为正如James Kanze在他的回答中解释的那样,临时不能绑定转义为operator<<的免费const char *重载中的非const左值引用。