From: David Wilkinson on
Vahid 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.

Vahid:

As others have noted you have some problems with the signatures of
operator =() and operator ==().

As to HashKey(), you probably don't really need a hashed map, in which
case you could use std::map from the standard library (std::map is a
tree-based map, not a hash map).

Personally I never use the MFC collection classes. The standard libraray
ones are just much better designed, IMHO. Most recent C++
implementations also have hash_map, if you really need a hashed map.

--
David Wilkinson
Visual C++ MVP
From: Arman Sahakyan on

"David Wilkinson" wrote:

> Vahid 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.
>
> Vahid:
>
> As others have noted you have some problems with the signatures of
> operator =() and operator ==().
>
> As to HashKey(), you probably don't really need a hashed map, in which
> case you could use std::map from the standard library (std::map is a
> tree-based map, not a hash map).

In addition:
In this case he needs to overload operator < because std::map uses < to sort
(insert into its search tree) elements of the container.



--
======
Arman

From: David Wilkinson on
Arman Sahakyan wrote:

>> As others have noted you have some problems with the signatures of
>> operator =() and operator ==().
>>
>> As to HashKey(), you probably don't really need a hashed map, in which
>> case you could use std::map from the standard library (std::map is a
>> tree-based map, not a hash map).
>
> In addition:
> In this case he needs to overload operator < because std::map uses < to sort
> (insert into its search tree) elements of the container.

Ah, yes. I forgot about that. But no big deal. Easier than writing a
hash function.

--
David Wilkinson
Visual C++ MVP
From: Vahid on
Thanks a lot guys for your suggestions. Since I'm not used to standard
library (compared to MFC), I picked CMap right away. And before
reading your messages, I had come up with the following which compiled
ok:

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

template<> AFX_INLINE UINT AFXAPI HashKey(SDataType& key)
{
return HashKey((DWORD_PTR) key.nNamespace) + HashKey ((DWORD_PTR)
key.nDataType);
}

Arman, how do you compare this with your suggestion. As you see, I do
not use reference parameters here.

Thanks again,
Vahid.

From: David Wilkinson on
Vahid wrote:
> Thanks a lot guys for your suggestions. Since I'm not used to standard
> library (compared to MFC), I picked CMap right away. And before
> reading your messages, I had come up with the following which compiled
> ok:
>
> struct SDataType {
> unsigned long nNamespace;
> unsigned long nDataType;
> SDataType& operator=(SDataType s2) { nNamespace = s2.nNamespace;
> nDataType = s2.nDataType; return *this; }
> bool operator==(SDataType s2) const { return ((nNamespace ==
> s2.nNamespace) && (nDataType == s2.nDataType)); }
> };
>
> template<> AFX_INLINE UINT AFXAPI HashKey(SDataType& key)
> {
> return HashKey((DWORD_PTR) key.nNamespace) + HashKey ((DWORD_PTR)
> key.nDataType);
> }
>
> Arman, how do you compare this with your suggestion. As you see, I do
> not use reference parameters here.

Vahid:

I think all these methods should be taking const SDataType& as argument.
Actually, you do not need operator =(), because you are just doing
member-wise assignment, which is what the default implementation does.

Again, IMHO, before you get too deeply involved in the MFC collection
classes, consider the C++ library ones instead.

--
David Wilkinson
Visual C++ MVP