我想使用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<<
工作正常。
我该如何解决这个问题? 谢谢!
答案 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左值引用。