我遇到了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..
这两个语句之间的唯一区别是参数顺序。为什么第一个语句失败而第二个语句起作用?
最佳答案
简短答案
问题是ss << L"text"
给您的是std::wostream
,而不是std::wstringstream
。
您仅为operator<<
创建了std::wstringstream
,因此下一个操作(您要在a
上尝试执行此操作)失败。
长答案
当你写类似
ss << L"text" << a << endl;
您没有调用带有四个参数的函数。
实际上,您正在链接多个操作:
((ss << L"text") << a) << endl;
之所以可行,是因为每个
operator<<
操作都返回对原始流对象的引用,因此您可以继续以此方式链接其他操作。但是,因为iostreams形成了一个继承层次结构,并且因为
operator<<
适用于任何输出流,所以您对wstringstream
进行操作的返回类型比wstringstream
更为具体。实际上,
ss << L"text"
的计算结果为wostream&
(wostream
是wstringstream
的基类之一)。该引用仍然引用相同的原始流对象...但是它具有基类类型。因此,涉及
a
的第二个操作具有以下 Activity 操作数:wostream&
(在LHS上)Test
但是您没有
wostream& operator<<(wostream&, Test const&)
。您仅创建了wstringstream& operator<<(wstringstream& sstream, Test const& test)
,所以没有匹配项。因此,实际上,当为宽iostream创建一个
operator<<
时,应该使它适用于所有wostream
(显然,没有理由将其限制为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
类的对象正确地流式传输到wostream
,ostream
以及它们的所有后代中。