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中)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中,通过添加非成员函数(27.7.3.9)修复了此问题,该函数将第一个参数作为右值引用,然后将调用转发给相应的函数(成员或非成员).所以打印XYZ后跟ABC:
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中也有类似的设备 - 如果可以使用它们,你可以使用它们.