C++字符串流内联

C++ stringstream inline

本文关键字:字符串 C++      更新时间:2023-10-16

我想使用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中编译良好,但输出如下:

"0x401d0a50.1abc">

因此,stringstream似乎将第一个字符串视为指针并输出地址。随后的operator<<工作良好。

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

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

编辑:

两点:首先,正如已经指出的,g++确实做了你所做的如果指定-std=c++11,则需要。正如T.C.所指出的在§27.7.3.9中规定,为具有std::istream的右值参考的所有<<参数其次,周围的经典作品是以启动表达式CCD_ 13。flush是一个成员函数(因此可以在一个临时(,它返回一个std::ostream&(所以所有其他链接很好(;它对CCD_ 16。

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

R值流插入[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

它显然比采用const void *的成员operator<<更好地匹配,因此在C++11模式中由过载分辨率选择。在C++98模式中,这个重载不存在(因为没有右值引用(,唯一可行的重载是成员operator<<(因为,正如James Kanze在他的回答中解释的那样,临时重载不能绑定到使用const char *的自由operator<<重载中的非常量左值引用(。