Deepak Garg
Deepak Garg

Reputation: 356

C++ map not behaving properly

I have defined my class SumClass and trying to use it in a map as shown in the code below. I have defined the required <, = and == operator.

#include <iostream>
#include <vector>
#include <map>

using namespace std;

class SumClass {
    public:
    int id;
    int sum;
    SumClass() { id = sum = 0;}
    bool operator<(const SumClass& rhs) const{
        if( (id < rhs.id) && (sum< rhs.sum)) return true;
        else return false;
    }
    bool operator==(const SumClass& rhs) const{
        //if(this == &rhs) return true;
        if( (id == rhs.id) && (sum == rhs.sum) ) return true;
        else return false;
    }
    void set(int idd, int summ) { id = idd; sum = summ; }
    SumClass& operator=(const SumClass& rhs){
        id = rhs.id;
        sum = rhs.sum;
        return *this;
    }
};

void test(){
    map<SumClass, int> m;
    SumClass temp;
    temp.set(0,3);
    m[temp] = -1;
    temp.set(-1, 3);
    m[temp] = -1;
    temp.set(-1, 2);
    m[temp] = -1;
    temp.set(0, 1);
    cout << "Test: " << m[temp] << endl;
}


int main(){
    test();
}

The output of the code above is: "Test: -1". But the expected output is "Test: 0" as the SumClass element I am trying to find is not present in the map. Can anyone please point what am I doing wrong ?

Upvotes: 0

Views: 138

Answers (4)

Robᵩ
Robᵩ

Reputation: 168596

Your operator< does not provide a strict weak ordering.

Try this:

bool operator<(const SumClass& rhs) const{
  return std::tie(id, sum) < std::tie(rhs.id, rhs.sum);
}

Or, if you cannot use C++11 features:

bool operator<(const SumClass& rhs) const{
  return std::make_pair(id, sum) < std::make_pair(rhs.id, rhs.sum);
}

Upvotes: 5

Werner Henze
Werner Henze

Reputation: 16726

map::operator[] is trying to find the value in the map. If it finds it, it returns a reference to it. If it does not find it, then it creates it. You might consider using map::find.

Upvotes: 0

ecatmur
ecatmur

Reputation: 157314

You haven't defined the required operators; your operator< is not a strict weak ordering.

For example, (0, 0) < (1, 1), but neither (0, 0) < (0, 1) nor (0, 1) < (1, 1) holds, violating transitivity of equivalence.

See Operator< and strict weak ordering for how to write a strict weak ordering.

Upvotes: 2

John Dibling
John Dibling

Reputation: 101446

I suspect this is wrong:

 bool operator<(const SumClass& rhs) const{
        if( (id < rhs.id) && (sum< rhs.sum)) return true;
        else return false;
    }

Are they really both always going to have this relation?

Upvotes: 0

Related Questions