A Question about std::map class

J

JustSomeGuy

I have been trying out the map class in my application and noticed
something I can't explain....

My Key class was

class Key
{
unsigned short group;
unsigned short element;

bool operator< (const Key & r)
{
if (group > r.group) return(false);
if (element >= r.element) return(false);
return true;
}

...
};

I assumed that I also need edcopy constructors and assignment operators
for the Key and Value classes....
So I wrote those as well.....

However when I dump the map list sequentially I noticed that many
key/values were missing...
In fact only entries where both the group and element were unique...

ie.

0x0010, 0x0010 wouldn't exist if 0x0009, 0x0010 existed...

I assumed it was a problem with my operator< for the key class ...
so I re-wrote the key class to combine the two shorts into on long

ie.
unsigned long grp_elem = (unsigned long) group << 16 | (unsigned
long) element;

Then the operator< function looked simply like:

bool operator<(const Key & r)
{
return(grp_elem < r.grp_elem);
}

Then all worked well....
I don't like the fact that I had to do this to my Key class but its the
only way i could get things to work...
Can you see why I wasn't able to get it to work the original way?

TIA
Brian.
 
J

John Harrison

I have been trying out the map class in my application and noticed
something I can't explain....

My Key class was

class Key
{
unsigned short group;
unsigned short element;

bool operator< (const Key & r)
{
if (group > r.group) return(false);
if (element >= r.element) return(false);
return true;
}

...
};

I assumed that I also need edcopy constructors and assignment operators
for the Key and Value classes....
So I wrote those as well.....

You certainly don't for Key, the compiler generated versions will copy
shorts correctly. I can't see Value so I don't know about that.

However when I dump the map list sequentially I noticed that many
key/values were missing...
In fact only entries where both the group and element were unique...

ie.

0x0010, 0x0010 wouldn't exist if 0x0009, 0x0010 existed...

I assumed it was a problem with my operator< for the key class ...
Right.

so I re-wrote the key class to combine the two shorts into on long

ie.
unsigned long grp_elem = (unsigned long) group << 16 | (unsigned
long) element;

Then the operator< function looked simply like:

bool operator<(const Key & r)
{
return(grp_elem < r.grp_elem);
}

Then all worked well....
I don't like the fact that I had to do this to my Key class but its the
only way i could get things to work...
Can you see why I wasn't able to get it to work the original way?

Consider this

x.group = 1; x.element = 1;
y.group = 0; y.element = 2;

x < y; // this is false
y < x; // this is false too!!

So you have two keys which are different but both are less than the other.
That is why map got confused.

Here's how to write operator<

bool operator< (const Key & r)
{
return group < r.group ||
(group == r.group && element < r.element);
}

john
 
D

Dave Townsend

Brian,

I think you're problem is in your less function:

bool operator< (const Key & r)
{
if (group > r.group) return(false);
if (element >= r.element) return(false);
return true;
}

this SHOULD be
bool operator< (const Key & r)
{
if (group > r.group) return(false);
if (group == r.group && element >= r.element) return(false);
return true;
}

it looks to me that if group < r.group, but element > = r.elemn you'd return
false,
this would 'splain the funny problems you are seeing with the missing keys.

dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,172
Messages
2,570,933
Members
47,472
Latest member
blackwatermelon

Latest Threads

Top