Thanks for the tip, Curt!

Mike 

-----Original Message-----
From: Curt Arnold [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, April 23, 2008 9:30 PM
To: Log4CXX User
Subject: Re: Problem logging unicode MFC/ATL CString with LOG4CXX_*
macros


On Apr 23, 2008, at 8:12 PM, Jara, Mike SEA wrote:

> I'm having trouble getting (Windows) MFC or ATL CStrings to log
> properly, when using the LOG4CXX_* macros.  For example, this will log
> the pointer's hex value, rather than the string contents:
>
> CString sMyString(_T("Test CString"));
> LOG4CXX_DEBUG(MyLogger, sMyString);
>
> CString does implement a cast operator to LPCTSTR (wchar_t* in my  
> case).
> If I explicitly call this, the string logs properly:
>
> CString sMyString(_T("Test CString"));
> LOG4CXX_DEBUG(MyLogger, (LPCTSTR)sMyString);
>
> I would expect this cast operator to be implicitly called inside
> MessageBuffer, to make the argument comply with the function  
> signature.
> I think this is the function that should be called:
>
> WideMessageBuffer& MessageBuffer::operator<<(const wchar_t* msg);
>
> But when I step through in the debugger, I see that there is a global
> cast operator called instead.  I assume it's a better fit, as far as  
> the
> compiler's concerned:
>
> template<class V>
> std::ostream& operator<<(MessageBuffer& os, const V& val) {
>   return ((std::ostream&) os) << val;
>
> I tried commenting this cast operator out, and then I no longer have  
> to
> cast my CString!  But I'm afraid this was probably put in for a  
> reason,
> and I hate to just hack something when I don't completely understand  
> it.
> Does anyone know if I can safetly remove this?  Looking at the change
> list, I see it was added by "carnold" on 11/6/07, revision number
> 592542.
>
> I'm using the last snapshot before the 0.10 release, by the way.
>
> Any help would be appreciated.
>
> Thanks!
> Mike


The template that you mentioned basically says that when attempting to  
insert, you do not recognize the right hand side as a recognized  
string type (char*, wchar_t*, std::string, std::wstring), then use any  
available insertion operator for a std::ostream and force the rest of  
the expression to be char* based.

What you'd like to have is something like the following in scope:

#if defined(_UNICODE)
WideMessageBuffer& operator<<(MessageBuffer& buf, const CString& str) {
     return buf << (const wchar_t*) str;
}
WideMessageBuffer& operator<<(WideMessageBuffer& buf, const CString&  
str) {
     return buf << (const wchar_t*) str;
}
#else
CharMessageBuffer& operator<<(MessageBuffer& buf, const CString& str) {
     return buf << (const char*) str;
}
CharMessageBuffer& operator<<(CharMessageBuffer& buf, const CString&  
str) {
     return buf << (const char*) str;
}
#endif

which should take precedence over the fallback insertion operation.

Reply via email to