Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Use of CString key in CMap

2,224 views
Skip to first unread message

Kjell Arne Johansen

unread,
Apr 4, 2008, 2:31:00 AM4/4/08
to
Hi

I have a question about the use of CString as a key in a CMap. Is that okay?
I want to get an object using a string name. Is that okay or will I
sometime get the wrong object because the haskey could be the same for two
different strings?

CMap<CString, CString &, csomecobject, csomecobject &> m_map csomecobject;

This hash key I found in CodeGuru, but I am not able to see if it is a good
has key.

template<>
inline UINT AFXAPI HashKey<CString&> (CString& strKey)
{
LPCSTR key = strKey;
UINT nHash = 0;
while (*key)
{
nHash = (nHash<<5) + nHash + *key++;
}
return nHash;
}

Does anyone have knowledge about this?

Regards Kjell Arne Johansen

David Ching

unread,
Apr 4, 2008, 4:35:44 AM4/4/08
to
"Kjell Arne Johansen" <KjellArn...@discussions.microsoft.com> wrote in
message news:A75619A3-618B-4BB9...@microsoft.com...

> Hi
>
> I have a question about the use of CString as a key in a CMap. Is that
> okay?
> I want to get an object using a string name. Is that okay or will I
> sometime get the wrong object because the haskey could be the same for two
> different strings?
>
> CMap<CString, CString &, csomecobject, csomecobject &> m_map
> csomecobject;
>
> This hash key I found in CodeGuru, but I am not able to see if it is a
> good
> has key.
>

I would use CMapStringToObj as-is, without worrying about the hash function.
WIth maps, it is assumed there are unique keys for each object. The map can
contain only one instance of each key, so if you were to:

CMapStringToOb map;
map["geneva"] = switzerlandObject;
map["geneva"] = alpsObject;

then switzerlandObject would no longer be in the map, having been replaced
with alpsObject.

The hash function is an internal implementation to the map, it enables using
a fixed size container such as an array of linked lists to put the objects
into. The hash function then would determine which element of the array
would hold each object (the object would in that element's linked list).

But the hash function does not allow multiple instances of the same key to
be put into the map.

-- David


Giovanni Dicanio

unread,
Apr 4, 2008, 4:47:18 AM4/4/08
to

"Kjell Arne Johansen" <KjellArn...@discussions.microsoft.com> ha
scritto nel messaggio
news:A75619A3-618B-4BB9...@microsoft.com...

> I have a question about the use of CString as a key in a CMap. Is that
> okay?

To add to David's correct answer of using CMapStringToOb, I would also
suggest to use std::map.

One of the reasons I like std::map better than CMap is that you don't need
to provide a custom hash-key generator for std::map (or, at least, I never
had to do that). Instead, it seems that you must provide that with CMap (at
least for CString key...).

Moreover, with std::map you can have type-safety (because you can specify
the exact template value type T), instead with CMapStringToOb the "value"
type (in "key -> value" association) is a CObject *, so you kind of loose
type safety (or at least, it is not as robust and strict as in std::map).

Moreover, if you compare std::map and CMap definitions, you can note how
std::map is simpler (you just need to specify two template types: the key
type and value type - you can specify also other details, like compare
function and allocator, but default ones are also provided):

// std::map< Key, Value >
// (default compare function and allocator used)
std::map< CString, CSomeObject > m_map;

// CMap
// (You must specify 4 types...)


CMap<CString, CString &, csomecobject, csomecobject &> m_map csomecobject;

Giovanni

Giovanni Dicanio

unread,
Apr 4, 2008, 4:49:55 AM4/4/08
to

"David Ching" <d...@remove-this.dcsoft.com> ha scritto nel messaggio
news:ALlJj.112$vF....@newssvr21.news.prodigy.net...

> CMapStringToOb map;
> map["geneva"] = switzerlandObject;
> map["geneva"] = alpsObject;

I'm sure that David meant map[ _T("geneva") ] here.

It is important to put the _T() "decorator" (but I would define it a kind of
"uglyfier"...) so in Unicode builds the string literal is actually converted
to Unicode UTF-16 string literal L"geneva".

G

Giovanni Dicanio

unread,
Apr 4, 2008, 4:54:55 AM4/4/08
to

"Giovanni Dicanio" <giovanni...@invalid.com> ha scritto nel messaggio
news:eAPCMFj...@TK2MSFTNGP06.phx.gbl...

>
> "David Ching" <d...@remove-this.dcsoft.com> ha scritto nel messaggio
> news:ALlJj.112$vF....@newssvr21.news.prodigy.net...
>
>> CMapStringToOb map;
>> map["geneva"] =

Moreover, I was just realizing that that code could also compile in Unicode
builds, because CString has *implicit* (conversion) constructors from char*
to wchar_t*... However, I would prefer a L"geneva" string literal (using
_T() preprocessor expansion), instead of run-time penalty to convert from
char* to wchar_t*.

Giovanni

Kjell Arne Johansen

unread,
Apr 4, 2008, 5:21:00 AM4/4/08
to
Hi

Thank you for your answer.
As I understand it a good haskey will make lookup very fast, maybe dependent
of the string keys?

If they string keys are very much the same e.g. _T("abc1"), _T("abc2"),
_T("abc3") lookup will take longer time than if the string keys were totaly
different?

Another question regading string keys and mfc supported maps:
What if I want to map string to int?
E.g.
CMap<CString, CString &, int, int&> m_map;

I also have a case where I need to lookup an int number using a string key.
I have tried it using the current haskey.
Is that okay?
I could not find any mfc mapstringtoint.

Regards Kjell Arne Johansen

Kjell Arne Johansen

unread,
Apr 4, 2008, 5:25:00 AM4/4/08
to
Thank you very much for your answer.

I have always used the mfc stuff. Maybe it is time to try something else.
I also need look up a in number from string key.
E.g.
CMap<CString, CString &, int, int&> m_map.

I assume that can be done with std::map?


Regards Kjell Arne Johansen

Giovanni Dicanio

unread,
Apr 4, 2008, 5:44:29 AM4/4/08
to

"Kjell Arne Johansen" <KjellArn...@discussions.microsoft.com> ha
scritto nel messaggio
news:6730389B-CC6D-47A7...@microsoft.com...

> Thank you very much for your answer.

You're welcome.


> I have always used the mfc stuff. Maybe it is time to try something else.

IMHO, STL containers like std::vector and std::map are better designed than
MFC ones.
The very good thing is that STL containers play very well with MFC classes
(for example, I prefer MFC CString instead of std::string/wstring, and you
can put MFC CString into STL containers).


> I also need look up a in number from string key.
> E.g.
> CMap<CString, CString &, int, int&> m_map.
>
> I assume that can be done with std::map?

Of course.
e.g.:

<code>

typedef std::map< CString, int > MapStringToInt;

MapStringToInt map;

map[ _T("Bob") ] = 10;
map[ _T("Sue") ] = 22;

</code>

Giovanni


Kjell Arne Johansen

unread,
Apr 4, 2008, 6:03:02 AM4/4/08
to
Thank you very much, I will give it a try.

Regards Kjell Arne Johansen

David Wilkinson

unread,
Apr 4, 2008, 8:50:51 AM4/4/08
to
Kjell Arne Johansen wrote:
> Thank you very much for your answer.
>
> I have always used the mfc stuff. Maybe it is time to try something else.
> I also need look up a in number from string key.
> E.g.
> CMap<CString, CString &, int, int&> m_map.
>
> I assume that can be done with std::map?

Kjell:

std::map<CString, int> m_map;

corresponds to

CMap<CString, const CString &, int, const int&> m_map;

Note that in recent MFC versions, CArray and CList have use a defaulted second
template parameter, but it is not possible to default the second and fourth
template parameters in CMap.

No hash function is needed for std::map, because it relies on ordering of the
keys, not hashing. I think hash_map may be in future versions of the C++
standard, but the original STL did not have it.

--
David Wilkinson
Visual C++ MVP

Kjell Arne Johansen

unread,
Apr 4, 2008, 9:06:00 AM4/4/08
to
Thank you very much for your kind help.

Regards Kjell Arne Johansen

David Ching

unread,
Apr 4, 2008, 11:07:07 AM4/4/08
to
"Kjell Arne Johansen" <KjellArn...@discussions.microsoft.com> wrote in
message news:46BAA990-8FDC-4ACF...@microsoft.com...

> Hi
>
> Thank you for your answer.
> As I understand it a good haskey will make lookup very fast, maybe
> dependent
> of the string keys?
>
> If they string keys are very much the same e.g. _T("abc1"), _T("abc2"),
> _T("abc3") lookup will take longer time than if the string keys were
> totaly
> different?
>

Yes, the hash function is responsible for selecting e.g. which element of
the array to store the object into. Ideally for the set of keys you are
storing, the hash function will pick each element the same number of times
so that each element has the same number of objects saved in it. This
minimizes the average lookup time since the number of items to check in any
element is as small as possible.

Generally, the hash function does well about distributing similar strings as
per your example, e.g. "abc1" and "abc2" and "abc3" will probably all go to
different elements and be ideal. But I'm not sure if any of the MFC maps
will let you optimize the hash function.

> Another question regading string keys and mfc supported maps:
> What if I want to map string to int?
> E.g.
> CMap<CString, CString &, int, int&> m_map;
>
> I also have a case where I need to lookup an int number using a string
> key.
> I have tried it using the current haskey.
> Is that okay?
> I could not find any mfc mapstringtoint.
>

No, there is no pre-built specialized class mapping a string to an int.
You'd use templates as you have done. But again, don't worry about the hash
function. You're optimizing something that you can assume does not need
optimizing unless you have concrete proof it is causing visible performance
impact. I've never had this be the case.

-- David


David Ching

unread,
Apr 4, 2008, 11:12:55 AM4/4/08
to
"Giovanni Dicanio" <giovanni...@invalid.com> wrote in message
news:uYYgsDjl...@TK2MSFTNGP05.phx.gbl...

>
> One of the reasons I like std::map better than CMap is that you don't need
> to provide a custom hash-key generator for std::map (or, at least, I never
> had to do that). Instead, it seems that you must provide that with CMap
> (at least for CString key...).

I'm not sure what you mean. You don't have to provide a "custom hash-key
generator" for CMap, and I'm not sure how to do that if it is even possible.


>
> Moreover, with std::map you can have type-safety (because you can specify
> the exact template value type T), instead with CMapStringToOb the "value"
> type (in "key -> value" association) is a CObject *, so you kind of loose
> type safety (or at least, it is not as robust and strict as in std::map).
>

This is true, however, using templates you could just as well say:

CMap<CString, CString &, CMyClass, CMyClass &> m_map;

and this has the additional advantage that CMyClass does not need to derive
from CObject.


> Moreover, if you compare std::map and CMap definitions, you can note how
> std::map is simpler (you just need to specify two template types: the key
> type and value type - you can specify also other details, like compare
> function and allocator, but default ones are also provided):
>
> // std::map< Key, Value >
> // (default compare function and allocator used)
> std::map< CString, CSomeObject > m_map;
>
> // CMap
> // (You must specify 4 types...)
> CMap<CString, CString &, csomecobject, csomecobject &> m_map
> csomecobject;
>

This is true, but siince the 2nd and 4th parameters are simply reference
types of the 1st and 3rd parameters, it's not as if it causes much brain
power to figure these out. OTOH, making sense out of STL causes significant
brain power....

-- David


Giovanni Dicanio

unread,
Apr 4, 2008, 12:14:55 PM4/4/08
to

"David Ching" <d...@remove-this.dcsoft.com> ha scritto nel messaggio
news:XzrJj.60$7Z2...@newssvr12.news.prodigy.net...

> I'm not sure what you mean.

Hi David,

I'm sorry if I wrote my ideas badly.

I would like to give you a C++ sample code:

<code>

// CMap
CMap< CString, const CString &, CString, const CString & > map1;
map1[ _T("Seattle") ] = _T("Washington");
map1[ _T("Napoli") ] = _T("Campania");

// std::map
std::map< CString, CString > map2;
map2[ _T("Seattle") ] = _T("Washington");
map2[ _T("Napoli") ] = _T("Campania");

</code>

This code does not compile under Visual C++ 9 (VS2008).

I get the following error:

error C2440: 'type cast' :
cannot convert from 'const CString' to 'DWORD_PTR'
j:\programmi\microsoft visual studio 9.0\vc\atlmfc\include\afxtempl.h 163

The error points in this template function in afxtempl.h:

<code>

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);
}

</code>

If I comment out the CMap version (where the problem is), the STL std::map
version compiles fine.

What should I do to use CMap *generic template* with CString?
Why doesn't it work simply, just like std::map?


> This is true, however, using templates you could just as well say:
>
> CMap<CString, CString &, CMyClass, CMyClass &> m_map;
>
> and this has the additional advantage that CMyClass does not need to
> derive from CObject.

You are right about using CMap generic template.
But my problem is that it seems that it does not compile with CString key...

Or am I missing something?


>> // CMap
>> // (You must specify 4 types...)
>> CMap<CString, CString &, csomecobject, csomecobject &> m_map
>> csomecobject;
>>
>
> This is true, but siince the 2nd and 4th parameters are simply reference
> types of the 1st and 3rd parameters, it's not as if it causes much brain
> power to figure these out. OTOH, making sense out of STL causes
> significant brain power....

You are right that 2nd and 4th parameters are simply reference types, so no
big brain power is required, but I don't like that: I mean: why add this
complexity of 2nd and 4th parameter types? It seems to me useless
complexity...

For STL, I believe that you can master that library better than me!
Moreover, you don't need to master *all* STL (I don't master all of it, of
course), you can just use some useful containers like vector or map...

However, I'm not in a position to "teach" anything to anyone :)
Mine are just simple advices, just IMHO.

I think that every programmer should use what he/she is familiar with and
likes.

G


David Ching

unread,
Apr 4, 2008, 10:32:16 PM4/4/08
to
"Giovanni Dicanio" <giovanni...@invalid.com> wrote in message
news:OtWxu9ml...@TK2MSFTNGP03.phx.gbl...

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


Cheers,
David


Giovanni Dicanio

unread,
Apr 5, 2008, 4:38:06 AM4/5/08
to

"David Ching" <d...@remove-this.dcsoft.com> ha scritto nel messaggio
news:QwBJj.113$CW...@newssvr11.news.prodigy.net...

> This excellent CodeProject article offers a lot more detail:
> http://www.codeproject.com/KB/architecture/cmap_howto.aspx

Thanks for your detailed post and for the article link.

Cheers,
G


David Wilkinson

unread,
Apr 5, 2008, 8:23:41 AM4/5/08
to
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 Ching

unread,
Apr 5, 2008, 10:18:36 AM4/5/08
to
"David Wilkinson" <no-r...@effisols.com> wrote in message
news:egZLjfxl...@TK2MSFTNGP03.phx.gbl...

> 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.
>

For me, It just seems the MFC classes follow the spirit of how these
collections are supposed to work... I mean, a map is another name for a
dictionary. CMap::Lookup() tells you whether your query is successful or
not instead of stupidly manufacturing a default object if you reference one
that is not there. What Webster's dictionary do you know that if you look
up a word that isn't in there, it creates an empty one on the fly,
corrupting your nice dictionary?

I think STL also has some API's specifically like Lookup() but for me I
could not even figure out how to use them when I first looked at the public
functions. You had to tell me! :-O Not to mention that STL code is truly
ugly and not very readable. Oh well, what's intuitve to someone is not for
others. I will say that thankfully the .NET collections share the same
spirt of the MFC collections, and these are truly easy to use and seem to
have the benefit of STL (things like nesting, etc.).


> 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...
>

The CodeProject article said the 2nd and 4th arguments were used throughout
the implementation, but really the true arguments were the 1st and 3rd ones.
I'm not sure the history of this. Perhaps the reason why MFC has pre-made
CStringTo<many things> classes is due to there is no easy way to generate a
HashKey from the object.

Thanks,
David


Giovanni Dicanio

unread,
Apr 5, 2008, 10:35:37 AM4/5/08
to

"David Ching" <d...@remove-this.dcsoft.com> ha scritto nel messaggio
news:0TLJj.18$pS4...@newssvr13.news.prodigy.net...

> I will say that thankfully the .NET collections share the same spirt of
> the MFC collections, and these are truly easy to use and seem to have the
> benefit of STL (things like nesting, etc.).

The .NET collections are the best ones.
They take the good things of both worlds (MFC and STL): e.g. they take the
high-readability of MFC collections with high-composibility of STL
collections.

Moreover, it seems that in a .NET collection you can put everything, instead
e.g. in a STL collection you can't put COM objects (pointers), instead you
must use CAdapt as an intermediate adapter...

Giovanni

David Wilkinson

unread,
Apr 5, 2008, 11:16:43 AM4/5/08
to
David Ching wrote:
> "David Wilkinson" <no-r...@effisols.com> wrote in message
> news:egZLjfxl...@TK2MSFTNGP03.phx.gbl...
>> 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.
>>
>
> For me, It just seems the MFC classes follow the spirit of how these
> collections are supposed to work... I mean, a map is another name for a
> dictionary. CMap::Lookup() tells you whether your query is successful or
> not instead of stupidly manufacturing a default object if you reference one
> that is not there. What Webster's dictionary do you know that if you look
> up a word that isn't in there, it creates an empty one on the fly,
> corrupting your nice dictionary?

David:

AFAICT, operator [] has the same behavior in std::map and CMap.

The CMap documentation says that it "cannot" be used as an r-value, which is
nonsense. What they mean is, it "should not" be used as an r-value if you do not
want a default value inserted if the key is not found.

std::map::find() is like CMap::Plookup(). The former returns an iterator, while
the latter returns a pointer. Same thing, conceptually. Dereferencing either
gives an element of the map, which is a pair in both cases.

There is no analog of CMap::Lookup() in std::map; you have to test the result of
find(). No big deal.

David Ching

unread,
Apr 5, 2008, 1:02:42 PM4/5/08
to
"David Wilkinson" <no-r...@effisols.com> wrote in message
news:OqbPPAzl...@TK2MSFTNGP02.phx.gbl...

> David:
>
> AFAICT, operator [] has the same behavior in std::map and CMap.
>
> The CMap documentation says that it "cannot" be used as an r-value, which
> is nonsense. What they mean is, it "should not" be used as an r-value if
> you do not want a default value inserted if the key is not found.
>

It's not nonsense. Instead of e.g.

if ( m_map[_T("geneva")] ) // inserts default "geneva" object

just do:

CString strGeneva;
if ( m_map.Lookup(_T("geneva"), strGeneva) ) // returns true if it
exists


I don't know of any uses when I desire a default value to be manufactured.
Ever. Like I said, a standard $1 dictionary doesn't do it, and I don't want
something supposedly modelling a dictionary to do it.


> std::map::find() is like CMap::Plookup(). The former returns an iterator,
> while the latter returns a pointer. Same thing, conceptually.
> Dereferencing either gives an element of the map, which is a pair in both
> cases.
>
> There is no analog of CMap::Lookup() in std::map; you have to test the
> result of find(). No big deal.
>

Well, perhaps that's why I don't like STL. Iterators are especially
unreadable, and I don't want to deal with them just to lookup something in
my map.

Thanks,
David


David Wilkinson

unread,
Apr 5, 2008, 2:03:42 PM4/5/08
to
David Ching wrote:
>> The CMap documentation says that it "cannot" be used as an r-value, which
>> is nonsense. What they mean is, it "should not" be used as an r-value if
>> you do not want a default value inserted if the key is not found.
>>
>
> It's not nonsense. Instead of e.g.
>
> if ( m_map[_T("geneva")] ) // inserts default "geneva" object
>
> just do:
>
> CString strGeneva;
> if ( m_map.Lookup(_T("geneva"), strGeneva) ) // returns true if it
> exists
>
>
> I don't know of any uses when I desire a default value to be manufactured.
> Ever. Like I said, a standard $1 dictionary doesn't do it, and I don't want
> something supposedly modelling a dictionary to do it.

David:

But CMap and std::map are no different in this regard. They both add a default
object. The code

if ( m_map[_T("geneva")] )

{
}

is not the right way to test if "geneva" is in the map in either CMap or
std::map. In std::map you should use the find() method (which is similar to
PLookup()).

David Ching

unread,
Apr 5, 2008, 5:40:55 PM4/5/08
to
"David Wilkinson" <no-r...@effisols.com> wrote in message
news:ub6Pjd0...@TK2MSFTNGP05.phx.gbl...

> David:
>
> But CMap and std::map are no different in this regard. They both add a
> default object. The code
>
> if ( m_map[_T("geneva")] )
> {
> }
>
> is not the right way to test if "geneva" is in the map in either CMap or
> std::map. In std::map you should use the find() method (which is similar
> to PLookup()).
>

Right, so we agree it's not nonsense? I object to std::map::find()
returning an iterator; it's not as clean as a simple bool.

STL does the job, but really, the only people that seem to like it are cross
platform people. Dedicated Windows programmers think differently, in
general. Or maybe that's just me.

-- David


Giovanni Dicanio

unread,
Apr 5, 2008, 6:24:25 PM4/5/08
to

"David Ching" <d...@remove-this.dcsoft.com> ha scritto nel messaggio
news:HlSJj.200$CW....@newssvr11.news.prodigy.net...

> I object to std::map::find() returning an iterator; it's not as clean as a
> simple bool.

I agree with you about std::map::find.

I would prefer code like:

if ( ! myMap.find( key ) )
...

instead of :

if ( myMap.find( key ) == myMap::end )
...
... iterator == map::end
... means: "no element found"

The find-returning-boolean is more intuitive and clearer to read.

I recall that I wrote a simple custom template "map" class (calling it
Dictionary) just wrapping std::map, and using coding conventions like
PascalCasing (that I prefer to underscore_casing ) and I added some methods
like a substitute for "find", returning a bool (I called it ContainsKey).
The implementation is trivial, of course (just kind of a little wrapper to
some of std::map methods), but it helped me building code of a quality I
prefer.


> STL does the job, but really, the only people that seem to like it are
> cross platform people. Dedicated Windows programmers think differently,
> in general. Or maybe that's just me.

For me, the very good point of STL is its container composibility. e.g. you
can build maps storing string-arrays or other objects, and it all works well
in STL. And STL containers work well also with "external" classes like
CString (which is not part of STL). From this particular point of view, STL
seems to me very well designed, IMHO.

Moreoever, the iterators help you to strongly decouple the containers and
the algorithms, i.e. thanks to the iterators, you can implement (or use)
some generic algorithms, without knowing the details of the container type
storing the data. It's kind of programming towards an "interface" instead of
a "concrete" class.

However, some STL things could be made better, like your good point about
std::map::find (...and frankly speaking I don't like the
stl_naming_convention with underscores... but it's just my personal coding
"tastes" :)

Cheers,
G

David Wilkinson

unread,
Apr 5, 2008, 7:54:16 PM4/5/08
to
David Ching wrote:
> Right, so we agree it's not nonsense? I object to std::map::find()
> returning an iterator; it's not as clean as a simple bool.
>
> STL does the job, but really, the only people that seem to like it are cross
> platform people. Dedicated Windows programmers think differently, in
> general. Or maybe that's just me.

David:

What I think is nonsense is the CMap documentation on operator []:

"Thus it can be used only on the left side of an assignment statement (an
l-value). If there is no map element with the specified key, then a new element
is created.

There is no "right side" (r-value) equivalent to this operator because there is
a possibility that a key may not be found in the map. Use the Lookup member
function for element retrieval."

This implies to me that using operator [] as an r-value would give a compiler
error, which of course it does not (and can not). Rather, if the key is not
found, it adds an entry to the map (just like std::map does).

David Ching

unread,
Apr 5, 2008, 8:48:21 PM4/5/08
to
"David Wilkinson" <no-r...@effisols.com> wrote in message
news:uRUYch3...@TK2MSFTNGP05.phx.gbl...

> David:
>
> What I think is nonsense is the CMap documentation on operator []:
>
> "Thus it can be used only on the left side of an assignment statement (an
> l-value). If there is no map element with the specified key, then a new
> element is created.
>
> There is no "right side" (r-value) equivalent to this operator because
> there is a possibility that a key may not be found in the map. Use the
> Lookup member function for element retrieval."
>
> This implies to me that using operator [] as an r-value would give a
> compiler error, which of course it does not (and can not). Rather, if the
> key is not found, it adds an entry to the map (just like std::map does).
>

Well, we've already agreed the behavior of CMap and std::map are the same
when used as an r-value. The difference is Microsoft wisely understood that
most people consider adding a default value to the map is an abomination and
tells you up front and center how to avoid this unwanted behavior. So it
seems like we're disagreeing on documentation.

-- David


David Wilkinson

unread,
Apr 6, 2008, 10:54:45 AM4/6/08
to

David:

My problem with the documentation is that it says that you *cannot* use operator
[] as an r-value.

In fact, if you *know* that the key is in the map (as is often the case), then
operator [] is a fine way to retrieve values.

That's all.

[The things that I *really" dislike about the MFC collection classes are that
they are non-copyable, and the unnecessary confusion caused by the doubling of
the template arguments...]

David Ching

unread,
Apr 6, 2008, 1:12:25 PM4/6/08
to
"David Wilkinson" <no-r...@effisols.com> wrote in message
news:u%23ADoY$lIHA...@TK2MSFTNGP02.phx.gbl...

> David:
>
> My problem with the documentation is that it says that you *cannot* use
> operator [] as an r-value.
>
> In fact, if you *know* that the key is in the map (as is often the case),
> then operator [] is a fine way to retrieve values.
>
> That's all.
>
> [The things that I *really" dislike about the MFC collection classes are
> that they are non-copyable, and the unnecessary confusion caused by the
> doubling of the template arguments...]
>

Fair enough. Everyone has different "hot buttons". :-) For example, I
have never had to copy a collection, and typing in 2 extra parameters don't
bother me much.

Cheers,
David


Wenwei Peng

unread,
Apr 21, 2015, 9:57:27 PM4/21/15
to
在 2008年4月4日星期五 UTC+8下午2:31:00,Kjell Arne Johansen写道:
> Hi
>
> I have a question about the use of CString as a key in a CMap. Is that okay?
> I want to get an object using a string name. Is that okay or will I
> sometime get the wrong object because the haskey could be the same for two
> different strings?
>
> CMap<CString, CString &, csomecobject, csomecobject &> m_map csomecobject;
>
> This hash key I found in CodeGuru, but I am not able to see if it is a good
> has key.
>
> template<>
> inline UINT AFXAPI HashKey<CString&> (CString& strKey)
> {
> LPCSTR key = strKey;
> UINT nHash = 0;
> while (*key)
> {
> nHash = (nHash<<5) + nHash + *key++;
> }
> return nHash;
> }
>
> Does anyone have knowledge about this?
>
> Regards Kjell Arne Johansen

Title: The core of the core of the big data solutions -- Map
Author: pengwenwei
Email: wenwei19710430
Language: c++
Platform: Windows, linux
Technology: Perfect hash algorithm
Level: Advanced
Description: Map algorithm with high performance
Section MFC c++ map stl
SubSection c++ algorithm
License: (GPLv3)

Download demo project - 1070 Kb
Download source - 1070 Kb

Introduction:
For the c++ program, map is used everywhere.And bottleneck of program performance is often the performance of map.Especially in the case of large data,and the business association closely and unable to realize the data distribution and parallel processing condition.So the performance of map becomes the key technology.

In the work experience with telecommunications industry and the information security industry, I was dealing with the big bottom data,especially the most complex information security industry data,all can’t do without map.

For example, IP table, MAC table, telephone number list, domain name resolution table, ID number table query, the Trojan horse virus characteristic code of cloud killing etc..

The map of STL library using binary chop, its has the worst performance.Google Hash map has the optimal performance and memory at present, but it has repeated collision probability.Now the big data rarely use a collision probability map,especially relating to fees, can’t be wrong.

Now I put my algorithms out here,there are three kinds of map,after the build is Hash map.We can test the comparison,my algorithm has the zero probability of collision,but its performance is also better than the hash algorithm, even its ordinary performance has no much difference with Google.

My algorithm is perfect hash algorithm,its key index and the principle of compression algorithm is out of the ordinary,the most important is a completely different structure,so the key index compression is fundamentally different.The most direct benefit for program is that for the original map need ten servers for solutions but now I only need one server.
Declare: the code can not be used for commercial purposes, if for commercial applications,you can contact me with QQ 75293192.
Download:
https://sourceforge.net/projects/pwwhashmap/files

Applications:
First,modern warfare can’t be without the mass of information query, if the query of enemy target information slows down a second, it could lead to the delaying fighter, leading to failure of the entire war. Information retrieval is inseparable from the map, if military products use pwwhashMap instead of the traditional map,you must be the winner.

Scond,the performance of the router determines the surfing speed, just replace open source router code map for pwwHashMap, its speed can increase ten times.
There are many tables to query and set in the router DHCP ptotocol,such as IP,Mac ,and all these are completed by map.But until now,all map are using STL liabrary,its performance is very low,and using the Hash map has error probability,so it can only use multi router packet dispersion treatment.If using pwwHashMap, you can save at least ten sets of equipment.

Third,Hadoop is recognized as the big data solutions at present,and its most fundamental thing is super heavy use of the map,instead of SQL and table.Hadoop assumes the huge amounts of data so that the data is completely unable to move, people must carry on the data analysis in the local.But as long as the open source Hadoop code of the map changes into pwwHashMap, the performance will increase hundredfold without any problems.


Background to this article that may be useful such as an introduction to the basic ideas presented:
http://blog.csdn.net/chixinmuzi/article/details/1727195

Wenwei Peng

unread,
Apr 22, 2015, 4:07:45 AM4/22/15
to
在 2008年4月4日星期五 UTC+8下午2:31:00,Kjell Arne Johansen写道:
> Hi
>
> I have a question about the use of CString as a key in a CMap. Is that okay?
> I want to get an object using a string name. Is that okay or will I
> sometime get the wrong object because the haskey could be the same for two
> different strings?
>
> CMap<CString, CString &, csomecobject, csomecobject &> m_map csomecobject;
>
> This hash key I found in CodeGuru, but I am not able to see if it is a good
> has key.
>
> template<>
> inline UINT AFXAPI HashKey<CString&> (CString& strKey)
> {
> LPCSTR key = strKey;
> UINT nHash = 0;
> while (*key)
> {
> nHash = (nHash<<5) + nHash + *key++;
> }
> return nHash;
> }
>
> Does anyone have knowledge about this?
>
> Regards Kjell Arne Johansen

Title: The core of the core of the big data solutions -- Map
Author: pengwenwei
Email:
0 new messages