how to customize compare function of std map class?

A

Andre Kostur

key_compare can only return true, false , but how about equal happens?

key_compare only needs to define a strict weak ordering.

If a < b, key_compare(a, b) returns true, key_compare(b, a) returns false.

If b < a, key_compare(a, b) returns false, key_compare(b, a) returns true.

If a == b, key_compare(a, b) returns false, key_compare(b, a) returns
false.
 
A

Alf P. Steinbach

* thinktwice:
key_compare can only return true, false , but how about equal happens?

key_compare compares two keys a and b as if via "a < b" with an
operator< defined for the key type, so equal keys will/should yield false.

a < b <=> b > a
!(a < b) <=> a >= b
b < a <=> a > b
!(b < a) <=> b >= a
a == b <=> (a >= b) && (b >= a) <=> !(a < b) && !(b < a)

And applying De Morgan's theorem,

a == b <=> !(a < b) && !(b < a) <=> !((a < b) || (b < a))
 
T

thinktwice

thanks, i have customize the compare function, but seems it doesn't
work. is there anything wrong?

struct myVariantCompare{
bool operator()(VARIANT v1, VARIANT v2)
{
if (v1.vt == v2.vt)
{
if (v1.vt == VT_UNKNOWN)
{
CComPtr<IUnknown> spUnk1(v1.punkVal);
if (spUnk1.IsEqualObject(v2.punkVal))
{
return false;
}
else
{
return v1.punkVal < v2.punkVal;
}
}
else
{
//assert, don't support other types
}
}
else
{
return v1.vt < v2.vt;
}
}
};
typedef std::multimap<CComVariant, long , _myVariantCompare> myMap;
typedef myMap::iterator myIter;
myMap map0;
....
myIter iter = map0.find(...); //iter doesn't equal map0.end() if
there's any item matches.

is there any problem with my compare function?
 
T

thinktwice

thanks, i have customize the compare function, but seems it doesn't
work. is there anything wrong?

struct myVariantCompare{
bool operator()(VARIANT v1, VARIANT v2)
{
if (v1.vt == v2.vt)
{
if (v1.vt == VT_UNKNOWN)
{
CComPtr<IUnknown> spUnk1(v1.punkVal);
if (spUnk1.IsEqualObject(v2.punkVal))
{
return false;
}
else
{
return v1.punkVal < v2.punkVal;
}
}
else
{
//assert, don't support other types
}
}
else
{
return v1.vt < v2.vt;
}
}


};


typedef std::multimap<CComVariant, long , _myVariantCompare> myMap;
typedef myMap::iterator myIter;
myMap map0;

is there any problem with my compare function?
 
D

dasjotre

thinktwice said:
thanks, i have customize the compare function, but seems it doesn't
work. is there anything wrong?

struct myVariantCompare{

inherit from binary_function
bool operator()(VARIANT v1, VARIANT v2)

this should be const
{
if (v1.vt == v2.vt)
{
if (v1.vt == VT_UNKNOWN)
{

why not assert here instead and loose the branch?
CComPtr<IUnknown> spUnk1(v1.punkVal);
if (spUnk1.IsEqualObject(v2.punkVal))
{
return false;
}
else
{
return v1.punkVal < v2.punkVal;

there is obviously a '<' operator for VARIANT::punkVal
therefore there is an equivalent for '=' operator too
so the spUnk1 seems superfluous.

I don't know COM and have no idea why you write it this way
}
}
else
{
//assert, don't support other types

this branch doesn't return
}
}
else
{
return v1.vt < v2.vt;
}
}


};


typedef std::multimap<CComVariant, long , _myVariantCompare> myMap;

I suppose CComVariant and VARIANT are the same type
typedef myMap::iterator myIter;
myMap map0;

is there any problem with my compare function?

to simplify:
change VARIANT with pair

bool operator()(pair const & v1, pair const & v2) const
{
if(v1.first == v2.first)
{
if(v1.second == v2.second)
return false;
else
return v1.second < v2.second;
}
else
return v1.first < v2.first;
}
 

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

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,173
Latest member
GeraldReund
Top