Re: Use of CString key in CMap
David Ching wrote:
I think you've exposed a limitation of the MFC maps. Apparently the key
type must be a type that can be converted to a DWORD_PTR (which is a 32-bit
DWORD on 32-bit Windows and a 64-bit value on 64-). So unless the type has
a conversion operator producing the DWORD_PTR, it can't be a key. CString
can't convert to a DWORD_PTR.
I did workaround this problem by declaring
CMap<LPCTSTR, LPCTSTR, CString, CString&> map1;
It's interesting that trying to follow the pattern of making the 2nd
parameter a reference, i.e..
CMap<LPCTSTR, LPCTSTR&, CString, CString&> map1;
resulted in a compiler error. I'm not sure what we give up by not making
the 2nd parameter a reference.
MFC does have a built in class CMapStringToString, but if you look at the
source code, it doesn't rely on templates at all, and both the key and value
are of type LPCTSTR and not CString!
This excellent CodeProject article offers a lot more detail:
http://www.codeproject.com/KB/architecture/cmap_howto.aspx
David:
This may be a good article, but for me it simply illustrates how much easier
std::map is to use than CMap. And I still don't understand the purpose of the
duplicated template arguments.
std::map<CString, int> just works. No muss, no fuss. With an MFC class as the
key, even.
Actually, I think the "correct" type for the second and fourth template
parameter in CMap is "const reference" (this is the default type of the second
parameter in recent versions of CArray and CList). It seems that
CMap<LPCTSTR, const LPCTSTR&, CString, const CString&> stringMap;
is allowed. [I didn't test it, but it compiles.]
CMap<CString, const CString&, CString, const CString&> stringMap;
will also work, but you have to provide your own hash function. You would think
that if MFC had provided a hash specializations for LPCTSTR, they would have
done it for CString also...
--
David Wilkinson
Visual C++ MVP