0

Hi i have custom key defined as shown below. When i create a std::map, i was under the impression that map will refer to operator== defined in my key to detect if two keys are same, but its not true. Can you please point me to correct logic for eliminating duplicates from this map?

class Key
{
public:
    Key(char * init, long l): equipNumber(l)
    {
            memcpy(initials, init, sizeof(initials));
    }

    bool operator==(const Key & other) const
    {
            bool result = true;
            cout << "Comparing: " << initials << " with " << other.initials;
            result &= (!memcmp(initials, other.initials, sizeof(initials)));
            cout << " And result is: " << result << endl;
            cout << "Comparing: " << equipNumber << " with " << other.equipNumber << endl;
            result &= (equipNumber == other.equipNumber);
            return result;
    }

    bool operator<(const Key & other) const
    {
            bool result = true;
            result &= (equipNumber < other.equipNumber);
            return result;
    }

private:
    char initials[5];
    long equipNumber;
};

2 Answers 2

2

The map calls operator < (or the given comparison functor) twice to determine equality: ! (a < b) && ! (b < a) implies a == b. As it happens, the first less-than operation of the pair is already performed as part of recursive descent, so there isn't much (or any) extra cost. And it greatly simplifies customization.

By the way,

        bool result = true;
        result &= (equipNumber < other.equipNumber);
        return result;

should probably be just return equipNumber < other.equipNumber;. And operations involving type conversions work more consistently with non-member overloads, so it's a good habit to define binary operators as friend or outside the class {} block.

Sign up to request clarification or add additional context in comments.

2 Comments

Can you please elaborate what you mean by "more consistently" ?
@Jimm The left-hand side is dispatched to the this implicit argument of the operator, so it isn't eligible for user-defined conversions. The right-hand side does see user-defined conversions, so you could have a<b defined but b<a undefined, or mismatched meanings, when a and b have different types.
2

A map<> orders keys according to Strict Weak Ordering. Strict Weak Ordering is based solely on a less-than type comparison. (Follow the link for a complete definition.)

Notably, Strict Weak Ordering considers objects a and b equivalent if !(a < b) && !(b < a), and map<> relies on that property.

If you do not provide a comparison function to map<> when you create the map, its comparison function defaults to std::less< Key >, which will invoke your operator<. That means it will not ever invoke your operator==, but it will invoke operator<. As long as your class is LessThan Comparable, then std::less< Key > will obey the properties of Strict Weak Ordering.

8 Comments

The equality operator is not needed at all. It isn't part of LessThanComparable. The relevant page from that site is this, but all that is obsolete and pre-standard. (It does say the greater-than operator should be implemented, at least if read in the same sense that the ISO standard is written. It still says nothing about equality, though.)
You are absolutely. I originally wrote it without the operator==, and then I second-guessed myself after scanning the SWO page. Two objects are considered 'equivalent' if !(a < b) and !(b < a). (And note equivalent, not equal.)
"SWO" is not relevant to the question at all. That is a requirement of functors, which OP did not implement.
How is it not? The question was "why doesn't map<> call operator== for my key type?" Keys to map<> are SWO. The default comparator for a map<> is less< key >.
No, the comparator functor is SWO. In this case the comparison is set by default to std::less< Key >, and Key is LessThanComparable.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.