468,765 Members | 1,212 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,765 developers. It's quick & easy.

Stringstreams and CStrings

Greetings!

I am running into a problem with implicit conversion of arguments when
trying to insert the contents of a CString object into a stringstream.

I am using the following typedef:

typedef std::basic_stringstream<TCHAR> ustringstream;

I have a function that somewhat resembles the following:

void DoSomething(CString TitleString)
{
TryToDoSomething();
if (ItDidntWork())
{
ustringstream theStream;
theStream << TitleString << _T("\n");
theStream << WhyItDidntWork();
TellTheUserItDidntWork(theStream);
}
}

If _UNICODE is not defined, TCHAR evaluates to char, and everybody's
happy. The stream is built as expected. But if _UNICODE is defined,
TCHAR becomes unsigned short, and instead of the expected title, the
stream contains a memory address in hexadecimal format.

Stepping into the code at the point of the first insertion, I see that
the first thing that happens is that CString's operator(LPCTSTR)
conversion method is called. Then basic_ostream<>'s operator<<(const
void*) method is called, which just puts the pointer's value into the
stream.

If I explictly cast TitleString to an LPCTSTR, the title is inserted
into the string as expected! But an explicit cast is really ugly, and
there's a lot of places where I'd have to do it. In an attempt to
find a better way, I wrote the following function:

uostream& operator<<(uostream& theStream, const CString& theString)
{
return operator<<(theStream, (LPCTSTR)theString);
}

But when this function was executed, the const char* that I got from
the cast was converted back into a CString and I ended up in an
endless loop and a stack overflow.

Can anybody explain what is going on here and what the best way out of
this morass is?

Thanks very much!

Rob Richardson
Jul 19 '05 #1
2 12467
rr*********@pressco.com (Rob Richardson) wrote in message news:<fe*************************@posting.google.c om>...
[snip]
If _UNICODE is not defined, TCHAR evaluates to char, and everybody's
happy. The stream is built as expected. But if _UNICODE is defined,
TCHAR becomes unsigned short, and instead of the expected title, the
stream contains a memory address in hexadecimal format.

Stepping into the code at the point of the first insertion, I see that
the first thing that happens is that CString's operator(LPCTSTR)
conversion method is called. Then basic_ostream<>'s operator<<(const
void*) method is called, which just puts the pointer's value into the
stream.


I encountered this very problem a few days ago. I think that what
happens is the following. The CString is converted to (const wchar_t*)
and then there are two possible operator<< overloads to call:
std::wostream & operator<<(std::wostream &os, const wchar_t *ws);
std::wostream & std::wostream::operator<<(void *p);
(well, actually the template versions of these functions, with wchar_t
and so on)

That is, a member function that writes a pointer and a nonmember
function that writes a wide string. But now, when you write:
wchar_t *x;
os << x;
which one is selected? Well, in MSVC6 it depends on the type of the
dynamic stream: if the stream is of type the base type (std::wostream)
the member function is selected (wrong), but if the stream is of a
derived type, say wstringstream, then the nonmember function is called
(right!).
I'm not sure, but I think that this is not standard, and the compiler
is wrong, maybe someone out there can confirm this.

Actually, there are a few more cases in your code, but the idea is the
same, sometimes MSVC takes it right, sometimes it doesn't.

My solution was to write a function like the following:

uostream& operator<<(uostream& theStream, const CString& theString)
{
theStream.write(theString, theString.GetLength());
return theStream;
}

Using the write member function all should be fine. And even the cast
goes away!!

HTH
Bobo
Jul 19 '05 #2
Had a similar problem and found that the compiler for some reason didn't see
the friend operator>> functions.

using std::operator<<;

solved the problem for me but I have no idea why it is needed.
Jul 19 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by raz | last post: by
2 posts views Thread by jordan | last post: by
reply views Thread by Doug Bailey | last post: by
1 post views Thread by JackHWarner | last post: by
95 posts views Thread by hstagni | last post: by
3 posts views Thread by JackC | last post: by
6 posts views Thread by kay kay | last post: by
reply views Thread by Marin | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.