15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Question about CMap and CString& as ARG_KEY

MARGHAL@gw2k.com
Thursday, April 18, 1996

Form: Memo
Text: (87 lines follow)
I'm using VC++ 4.1 with WinNT 3.51 Build 1057

I'm trying to use CMap for the first time, and I have run into a compile 
error that puzzles me.  This isn't a big problem because I've found a 
work-around, but, I'm hoping someone will explain why this compile error 
occurs.  I've checked the MFC faq, the MSDN, and three or four books on MFC 
including "Inside Visual C++" and "Win32 Programming Using Visual C++" and 
none of them have shed any light on the situation. In fact, "Win32 Prog. 
Using VC++" confuses me further because it says I can do what I'm trying to 
do.

My CMap declaration looks like this:
    
	typedef CMap CMapOfMyObs;
    
And I have an instantiation of the CMap in InitInstance that looks like 
this;

	CMapOfMyObs myObs;

CMyObject is derived from CObject with a trivial implementation like this:

	class CMyObject : public CObject
	{
	   DECLARE_DYNCREATE(CMyObject);

	public:
	   CMyObject() {};
	    ~CMyObject(){};
	    CMyObject& operator=( CMyObject rhs );
	    CMyObject( CMyObject& p );
	};

Pretty basic stuff so far.

When I compile, I get this compile error:
	
	E:\MSDEV\MFC\include\afxtempl.h(128) : error C2440: 'abstract declarator' :
	cannot convert from 'class CString' to 'unsigned long' (new behavior; 
please
	see help)

The code in afxtempl.h that is flagged by the error is this:

template
inline UINT AFXAPI HashKey(ARG_KEY key)
{
	// default identity hash - works for most primitive values
>>>>	return ((UINT)(void*)(DWORD)key) >> 4;    // <<<<<<<<< here's the line
}

It seems obvious that the problem is related to the ARG_KEY parameter to the 
CMap template. My ARG_KEY is a CString& and this HashKey function is 
expecting a simple type.  Now, on page 465 of Mike Blaszczak's book we find 
this statement:

"A template instantiation for CMap might look like this:
	CMap mapStates;  

This is very much like my CMap template instantiation.

On page 466 of the same book it says this about the CMap HashKey function:

"The MFC doesn't provide a default implementation for HashKey(), unless the 
collection is referencing a CString type.  The CString HashKey() function 
can be found in STREX.CPP... and looks like this: "

	UINT AFXAPI HashKey(LPCTSTR key)
	{
		UINT nHash = 0;
		while (*key)
			nHash = (nHash<<5) + nHash + *key++;
		return nHash;
	}


In checking, I find that this HashKey function is in MFC 4.x and I find that 
if I change my CMap declaration to use an LPCTSTR instead of a CString&, the 
compile error is eliminated.  (Note, my original code does not compile under 
VC++ 2.1 either.)

So my question is: is there a way I can use a CString& as my ARG_KEY 
parameter to the CMap template, or am I stuck using an LPCTSTR?

Al Margheim


Use Proportional Font: true




bop@gandalf.se
Monday, April 22, 1996

> From MARGHAL @ gw2k.com 
> I'm using VC++ 4.1 with WinNT 3.51 Build 1057
>
> I'm trying to use CMap for the first time, and I have run into a compile 
> error that puzzles me.  This isn't a big problem because I've found a 
> work-around, but, I'm hoping someone will explain why this compile error 
> occurs.  
[...]
>My CMap declaration looks like this:
>    
> typedef CMap CMapOfMyObs;
>    
[...]
> When I compile, I get this compile error:
> 
> E:\MSDEV\MFC\include\afxtempl.h(128) : error C2440: 'abstract declarator' :
> cannot convert from 'class CString' to 'unsigned long' (new behavior; 
> please see help)
>
> The code in afxtempl.h that is flagged by the error is this:
>
> template
> inline UINT AFXAPI HashKey(ARG_KEY key)
> {
>  // default identity hash - works for most primitive values
> >>>> return ((UINT)(void*)(DWORD)key) >> 4;    // <<<<<<<<< here's the line
> }
>
> It seems obvious that the problem is related to the ARG_KEY parameter to the 
> CMap template. My ARG_KEY is a CString& and this HashKey function is 
> expecting a simple type.  
>
> "The MFC doesn't provide a default implementation for HashKey(), unless the 
> collection is referencing a CString type.  The CString HashKey() function 
> can be found in STREX.CPP... and looks like this: "
>
> UINT AFXAPI HashKey(LPCTSTR key)
> {
>  UINT nHash = 0;
>  while (*key)
>   nHash = (nHash<<5) + nHash + *key++;
>  return nHash;
> }
>
[...]
> So my question is: is there a way I can use a CString& as my ARG_KEY 
> parameter to the CMap template, or am I stuck using an LPCTSTR?

You have it right here:
  "The MFC doesn't provide a default implementation for HashKey(), UNLESS the 
   collection is referencing a CString type."

So, if you want another hash function ("none of the above") you have to
provide it yourself! You might try something like:

UINT AFXAPI HashKey(CString& Key)
{
 UINT nHash = 0;
 for (int i = 0; i 



| Вернуться в корень Архива |