stringstream
我遇到了一个奇怪的问题。
#include "stdafx.h"
#include "iostream"
#include "sstream"
using namespace std;
struct Test
{
float f;
};
wstringstream& operator <<( wstringstream& sstream , const Test& test )
{
sstream << test.f;
return sstream;
}
int _tmain(int argc, _TCHAR* argv[])
{
Test a;
a.f = 1.2f;
wstringstream ss;
ss << L"text" << a << endl; // error C2679!
ss << a << L"text" << endl; // it works well..
getchar();
return 0;
}
问题在于:
ss << L"text" << a << endl; // error C2679!
ss << a << L"text" << endl; // it works well..
这两个陈述之间的唯一区别是参数顺序。为什么第一个语句失败而第二个语句有效?
答案 0 :(得分:9)
请勿将operator<<
仅限于使用wstringstream
,请将其写入以便适用于任何广泛的流:
std::wostream& operator <<(std::wostream& sstream, Test const& test)
{
return sstream << test.f;
}
或任何流(宽或窄):
template<typename CharT, typename TraitsT>
std::basic_ostream<CharT, TraitsT>&
operator <<(std::basic_ostream<CharT, TraitsT>& sstream, Test const& test)
{
return sstream << test.f;
}
答案 1 :(得分:4)
问题在于ss << L"text"
为您提供了std::wostream
,而不是std::wstringstream
。
您只为operator<<
创建了std::wstringstream
,因此下一个操作(您尝试在a
上执行的操作)失败。
当你写
之类的东西时ss << L"text" << a << endl;
你没有调用带有四个参数的函数。
事实上,你正在链接多个操作:
((ss << L"text") << a) << endl;
这是有效的,因为每个operator<<
操作都返回对原始流对象的引用,因此您可以继续以这种方式进行进一步的操作。
但是因为iostream构成了一个继承层次结构,并且因为operator<<
适用于任何输出流,所以wstringstream
上的操作的返回类型稍微不那么具体比wstringstream
。
事实上, ss << L"text"
评估为wostream&
(wostream
是wstringstream
基类之一。引用仍引用相同的原始流对象......但它具有基类类型。
因此,涉及a
的第二个操作具有以下活动操作数:
wostream&
(在LHS上)Test
(在RHS上) 但是你没有wostream& operator<<(wostream&, Test const&)
。您只创建了wstringstream& operator<<(wstringstream& sstream, Test const& test)
,因此无法匹配。
因此,实际上,在为广泛的iostream创建operator<<
时,您应该让它适用于所有 wostream
(显然没有理由将其限制为{ {1}}):
wstringstreams
更进一步,为什么要限制自己的广泛流?为什么不是正常的?
wostream& operator<<(wostream& sstream, Test const& test)
{
sstream << test.f;
return sstream;
}
现在,您可以正确地将template<typename CharT, typename TraitsT>
std::basic_ostream<CharT, TraitsT>&
operator<<(std::basic_ostream<CharT, TraitsT>& sstream, Test const& test)
{
sstream << test.f;
return sstream;
}
课程的对象流式传输到Test
s,wostream
及其所有后代。