From: Vahid on
I have a struct in my program defined as below:

struct SDataType {
unsigned long nNamespace;
unsigned long nDataType;
SDataType& operator=(SDataType& s2) { nNamespace = s2.nNamespace;
nDataType = s2.nDataType; return *this; }
bool operator==(SDataType s2) { return ((nNamespace ==
s2.nNamespace) && (nDataType == s2.nDataType)); }
};

And I have defined a CMap variable as below:

CMap<SDataType, SDataType&, unsigned int, unsigned int> map;

However, I get this compilation error:

error C2679: binary '=' : no operator found which takes a right-hand
operand of type 'const SDataType' (or there is no acceptable
conversion)

which refers to this portion of "template<class KEY, class ARG_KEY,
class VALUE, class ARG_VALUE>
void CMap<KEY, ARG_KEY, VALUE, ARG_VALUE>::GetNextAssoc(POSITION&
rNextPosition, KEY& rKey, VALUE& rValue) const" function in
afxtempl.h:

rKey = pAssocRet->key;

Does anyone know how this problem can be resolved? I'd appreciate your
help.

From: Joseph M. Newcomer on
I'd be inclined to define SDataType as a class rather than a struct, but I don't think
that's the problem. Your operator= is defined with a RHS of SDataType, but it appears
that one using const SDataType& is required. Exactly why, I'm not sure, but that appears
to be the source of the error.
joe

On 2 May 2007 18:32:54 -0700, Vahid <vahid.ha(a)gmail.com> wrote:

>I have a struct in my program defined as below:
>
>struct SDataType {
> unsigned long nNamespace;
> unsigned long nDataType;
> SDataType& operator=(SDataType& s2) { nNamespace = s2.nNamespace;
>nDataType = s2.nDataType; return *this; }
> bool operator==(SDataType s2) { return ((nNamespace ==
>s2.nNamespace) && (nDataType == s2.nDataType)); }
>};
>
>And I have defined a CMap variable as below:
>
>CMap<SDataType, SDataType&, unsigned int, unsigned int> map;
>
>However, I get this compilation error:
>
>error C2679: binary '=' : no operator found which takes a right-hand
>operand of type 'const SDataType' (or there is no acceptable
>conversion)
>
>which refers to this portion of "template<class KEY, class ARG_KEY,
>class VALUE, class ARG_VALUE>
>void CMap<KEY, ARG_KEY, VALUE, ARG_VALUE>::GetNextAssoc(POSITION&
>rNextPosition, KEY& rKey, VALUE& rValue) const" function in
>afxtempl.h:
>
>rKey = pAssocRet->key;
>
>Does anyone know how this problem can be resolved? I'd appreciate your
>help.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Vahid on
Thanks for your reply Joseph.

I have already tried a few combinations such as the one you suggested.

Yours will create the following errors:

error C2440: 'type cast' : cannot convert from 'SDataType' to
'DWORD_PTR' (refers to the "return" line in

template<class ARG_KEY>
AFX_INLINE UINT AFXAPI HashKey(ARG_KEY key)
{
// default identity hash - works for most primitive values
return (DWORD)(((DWORD_PTR)key)>>4);
}
)

plus the following error:

error C2678: binary '==' : no operator found which takes a left-hand
operand of type 'const SDataType' (or there is no acceptable
conversion)
D:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc
\include\afxtempl.h(1544) : see reference to function template
instantiation 'BOOL CompareElements<KEY,SDataType>(const TYPE *,const
ARG_TYPE *)' being compiled
with
[
KEY=SDataType,
TYPE=SDataType,
ARG_TYPE=SDataType
]

refering to

template<class TYPE, class ARG_TYPE>
BOOL AFXAPI CompareElements(const TYPE* pElement1, const ARG_TYPE*
pElement2)
{
ASSERT(AfxIsValidAddress(pElement1, sizeof(TYPE), FALSE));
ASSERT(AfxIsValidAddress(pElement2, sizeof(ARG_TYPE), FALSE));

return *pElement1 == *pElement2; // this line
}

From: Vahid on
I found the result. I had to override the "HashKey" function.

From: Arman Sahakyan on
Now you have two problems;
* == operator is not const [it is required because inside CMap are compared
constant objects]. So make it const.
* The HashKey function inside CMap cannot produce any hash value from
SDataType objects; SDataType objects should be able to turn into integer
value somehow [to calculate the hash code]. So define a DWORD operator
returning some unique value (usually returning the object's address will do).

After all, the following code is working;

struct SDataType {
unsigned long nNamespace;
unsigned long nDataType;
SDataType& operator = (const SDataType &s2)
{
nNamespace = s2.nNamespace;
nDataType = s2.nDataType;
return *this;
}
bool operator == (const SDataType &s2) const
{
return ((nNamespace == s2.nNamespace) && (nDataType == s2.nDataType));
}

operator DWORD_PTR () { return (DWORD_PTR ) this; }
};


typedef CMap<SDataType, SDataType &, UINT , UINT> CDataMap;

CDataMap myMap;


And another thing, you should check for equallity at the first line of
assignment operator to avoid harmful consequences of a=a statements;
if (this == &s2) return *this;



--
======
Arman


"Vahid" wrote:

> Thanks for your reply Joseph.
>
> I have already tried a few combinations such as the one you suggested.
>
> Yours will create the following errors:
>
> error C2440: 'type cast' : cannot convert from 'SDataType' to
> 'DWORD_PTR' (refers to the "return" line in
>
> template<class ARG_KEY>
> AFX_INLINE UINT AFXAPI HashKey(ARG_KEY key)
> {
> // default identity hash - works for most primitive values
> return (DWORD)(((DWORD_PTR)key)>>4);
> }
> )
>
> plus the following error:
>
> error C2678: binary '==' : no operator found which takes a left-hand
> operand of type 'const SDataType' (or there is no acceptable
> conversion)
> D:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\atlmfc
> \include\afxtempl.h(1544) : see reference to function template
> instantiation 'BOOL CompareElements<KEY,SDataType>(const TYPE *,const
> ARG_TYPE *)' being compiled
> with
> [
> KEY=SDataType,
> TYPE=SDataType,
> ARG_TYPE=SDataType
> ]
>
> refering to
>
> template<class TYPE, class ARG_TYPE>
> BOOL AFXAPI CompareElements(const TYPE* pElement1, const ARG_TYPE*
> pElement2)
> {
> ASSERT(AfxIsValidAddress(pElement1, sizeof(TYPE), FALSE));
> ASSERT(AfxIsValidAddress(pElement2, sizeof(ARG_TYPE), FALSE));
>
> return *pElement1 == *pElement2; // this line
> }
>
>