使用匿名字符串流来构造字符串

Jon*_*Mee 5 c++ string sstream

我想直接读入一个代码如下的字符串:

std::string myString(( std::ostringstream() << myInt << " "
                                            << myFloat << " "
                                            << std::boolalpha << myBool ).str());
Run Code Online (Sandbox Code Playgroud)

但VS2012给了我一个basic_ostream没有str()方法的投诉.

有没有办法用匿名字符串流来做到这一点?

Naw*_*waz 13

operator<<用于流收益std::ostream &不具有str()成员函数.你需要使用演员表.

static_cast<std::ostringstream&>(std::ostringstream() << etc).str()
Run Code Online (Sandbox Code Playgroud)

使用临时流时C++ 03和C++ 11之间的差异!

C++ 03

但要注意(在C++ 03中)std::ostringstream()创建一个临时对象,这意味着不能为第一个调用非成员重载,因为它们都接受第一个不能绑定到临时对象的参数.临时对象只能调用成员函数.operator<<<<std::ostream&

这意味着,以下将给你地址而不是字符串:

static_cast<std::ostringstream&>(std::ostringstream() << "XYZ").str()
Run Code Online (Sandbox Code Playgroud)

因为这需要过载char const*作为参数是一个非成员函数,它cannnot被调用,因此,上述代码最终调用成员函数,它接受void const*作为参数,从而"XYZ"隐式转换成void const*,打印地址字符串文字的.

一旦临时调用成员函数,剩下的链<< 可以调用非成员过载,因为成员函数返回std::ostream&现在能够结合到第一个参数非成员的过载operator<<.因此,以下代码将打印一个地址(而不是"XYZ")后跟字符串"ABC":

static_cast<std::ostringstream&>(std::ostringstream() << "XYZ" << "ABC").str()
Run Code Online (Sandbox Code Playgroud)

在线演示:

C++ 11

在C++ 11中,通过添加非成员函数(27.7.3.9)修复了此问题,该函数将第一个参数作为右值引用,然后将调用转发给相应的函数(成员或非成员).所以打印XYZ后跟ABC:


Joh*_*ing 7

basic_osstream::operator<<返回a basic_ostream,而不是a ostringstream.编译器不是骗你的.

我宁愿创建一个StringBuilder类型的设备.

class StringBuilder
{
public:
    template <typename T> inline StringBuilder& operator<<(const T& t)
    {
        mStream << t;
        return * this;
    }
    inline std::string get() const
    {
        return mStream.str();
    }
    inline operator std::string () const
    {
        return get();
    }
private:
    std::stringstream mStream;
};
Run Code Online (Sandbox Code Playgroud)

现在你可以:

std::string myString (StringBuilder() << myInt << " " << myFloat /*...*/);
Run Code Online (Sandbox Code Playgroud)

Boost中也有类似的设备 - 如果可以使用它们,你可以使用它们.