I’m experiencing a weird problem with 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;
}
The problem is here:
ss << L"text" << a << endl; // error C2679!
ss << a << L"text" << endl; // it works well..
The only difference between these two statements is argument order. Why does the first statement fail whereas the second one works?
Short answer
The problem is that
ss << L"text"gives you astd::wostream, not astd::wstringstream.You only created an
operator<<forstd::wstringstream, so the next operation (which you’re trying to do ona) fails.Long answer
When you write something like
you are not invoking a function with four arguments.
You are, in fact, chaining multiple operations:
This works because each
operator<<operation returns a reference to the original stream object, so that you can continue chaining further operations on in this manner.But because iostreams form an inheritance hierarchy, and because
operator<<is applicable to any output stream, the return type from your operation onwstringstreamis something a little less specific thanwstringstream.In fact,
ss << L"text"evaluates to awostream&(wostreambeing one ofwstringstream‘s base classes). The reference still refers to the same, original stream object… but it has a base class type.So, your second operation involving
ahas the following active operands:wostream&(on the LHS)Test(on the RHS)But you have no
wostream& operator<<(wostream&, Test const&). You only created awstringstream& operator<<(wstringstream& sstream, Test const& test), so there’s no match.So, in fact, when creating an
operator<<for wide iostreams you should make it work for allwostreams (clearly there is no reason to limit it towstringstreams):Going further, why limit yourself to wide streams? Why not normal ones too?
Now you will be able to stream objects of your
Testclass intowostreams,ostreams, and all their descendants, properly.