Re: CString not working as advertised

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Doug Harrison [MVP] wrote:

On Fri, 21 Apr 2006 08:38:16 -0400, David Wilkinson <no-reply@xxxxxxxxxxxx>
wrote:


Joseph M. Newcomer wrote:


CString kindOfFruit("bananas");
will compile because there is an overloaded constructor, overloaded for both LPCSTR and
LPCWSTR, and depending on the build, one or the other will do the appropriate conversion.
But the assignment statement doesn't work. I've seen it fail in a lot of programs.
joe


[snip]

Hi Joe:

Now that IS interesting. In VC7, you are right. The following will not compile in a UNICODE application:

CString kindOfFruit = "bananas";

However all of the following do:

CString kindOfFruit("bananas");

CString kindOfFruit = CString("bananas");

CString kindOfFruit;
kindOfFruit = "bananas";

CString kindOfFruit;
kindOfFruit += "bananas";

In my ideal world, none of them would compile (and I have fixed my VC6 headers so they don't). But why does the first one not compile? As I understand it, when you do

CString kindOfFruit = "bananas";

this is not an assignment (though assignment would work!). Rather, the compiler should first construct a temporary CString using the const char* constructor, and then initialize kindOfFruit using the copy constructor. It is also allowed to elide the temporary and use the const char* constructor directly, provided the first method would have been legal.

So why doesn't this work? Can it have to do with the fact that CString is a template class in VC7 onward?

C++ experts?

David Wilkinson

=====================


See if the relevant ctor is declared "explicit". If so, there's your
answer.


Hi Doug:

In VC7.1, none of the CStringT constructors is explicit (at least in the documentation). But CStringT is derived from CSimpleStringT, which does have an explicit constructor:

explicit CSimpleStringT(
IAtlStringMgr* pStringMgr
) throw( );

At this point my head started to spin. What is IAtlStringMgr? Anyway, I do not see how this explicit declaration discriminates between LPCSTR and LPCWSTR. Also, does explicit base constructor carry over to the derived class? CString has gotten very complicated!

IMO, no matter what, MS missed a big opportunity to get rid of all the conversion constructors when they redesigned the CString class using templates. They must make the coding of CStringT very complicated. In the standard library you can just do

typedef std::basic_string<TCHAR> tstring;

and you're done. No conversion constructors, thank you.

David Wilkinson
.



Relevant Pages

  • Re: CString not working as advertised
    ... compile in a UNICODE application: ... CString kindOfFruit; ... char* constructor, and then initialize kindOfFruit using the copy ...
    (microsoft.public.vc.mfc)
  • Re: CString not working as advertised
    ... The following will not compile in a UNICODE application: ... CString kindOfFruit; ... Rather, the compiler should first construct a temporary CString using the const char* constructor, and then initialize kindOfFruit using the copy constructor. ...
    (microsoft.public.vc.mfc)
  • Re: CString Speed and compiler optimization
    ... Empty checks for a few things and does a bit of stuff to release, or not, ... why this interest in what the optimiser does. ... has no way to know that a CString is initialised, in its constructor, to ...
    (microsoft.public.vc.mfc)
  • Re: string cast
    ... stirng's constructor to explicit, ... string s2 = "test" could not compile at all. ... struct X { ...
    (microsoft.public.vc.stl)
  • Re: TREE structure in MFC, how, where and why?
    ... I had not noticed the CString. ... >By using malloc, the constructor on your CString is not being called. ... >>terminal node and a tree node is that a terminal node has no children. ...
    (microsoft.public.vc.mfc)