Search code examples
c++stdset

set::find() not working with user define data type


When I am searching for a key which is not present in my set then find() instead of returning iterator to end is returning an iterator to an another object which is not equal to key but present in set.

I have no idea whats going wrong.

CODE

class node{
public:
    int a, b;
    node(int a, int b):a(a), b(b){}

    bool operator>(const node &ob)const{
        return (this->b - this->a) > (ob.b - ob.a);     
    }

    bool operator==(const node &ob)const{
        return ((this->a == ob.a) && (this->b == ob.b));
    }
};

void print(set<node,greater<node>> &s){
    cout << "[ ";
    for(const node &ob: s){
        cout << "(" << ob.a << "," << ob.b << ") ";
    }

    cout <<"]\n--------------------------------" << endl;
}
set<node,greater<node>> s;                  
int main(){
    s.insert(node(0,3));
    s.insert(node(3,8));
    print(s);
    s.erase(node(3,8));
    cout << "After erasing (3, 8)" << endl;
    print(s);
    cout << "Searching for key (3,6)" << endl;
    set<node,greater<node>>::iterator i = s.find(node(3,6));
    if(i == s.end()){
        cout << "Not Found" << endl;
    }else{
        cout << "Found : " << "(" << i->a << "," << i->b << ")" << endl;
    }
    return 0;
}

OUTPUT

[ (3,8) (0,3) ]
--------------------------------
After erasing (3, 8)
[ (0,3) ]
--------------------------------
Searching for key (3,6)
Found : (0,3)


Solution

  • When comparing objects as equal or not std::set uses the comparison function (i.e. greater<node> which uses node::operator>) but not node::operator== (as you expected).

    In imprecise terms, two objects a and b are considered equivalent if neither compares less than the other: !comp(a, b) && !comp(b, a).

    For node(3,6) and node(0,3), both operator> (node(3,6), node(0,3)) and operator> (node(0,3), node(3,6)) return false, then they're considered equivalent.