shashydhar
shashydhar

Reputation: 811

how does count in c++ stl set work?

So, I'm trying to check whether a particular object is already present in the set. For this, I use the count() method. Now, it doesn't seem to return the right answer. Let me explain the problem a bit more clearly --

I have declared a class this way

class Node{
        public:
                Node(int _state=0, int _cost=0)
                {
                        state = _state;
                        cost = _cost;
                }

                bool operator<(const Node& rhs)
                {
                        return cost < rhs.cost;
                }

                bool operator==(const Node& rhs)
                {
                        cout << "== operator method used" << endl;
                        if (rhs.state == state)
                                return true;
                        return false;
                }

                int state;
                int cost;
};

in my code, I declare a set like this --

set<Node*> myset;

after a few insertions, myset is like this {{1, 5}, {2, 6}, {3, 9}}

now I check whether {1, 7} is part of the set. How would it do it? I have written a operator== method in Node class, which is never called. Then on what basis does count() check if the object is already in the set?... I would want the count to work in a fashion that if {1, 5} is already there in myset, it should view {1, 7} as a duplicate entry.

Upvotes: 3

Views: 3112

Answers (6)

saeedn
saeedn

Reputation: 3378

STL does not use == operator for comparison, it uses < operator by default and it suffices, because a != b <=> a<b or b<a. You defined a set of pointers to Node. So your set does not behave the way you want. You should define set<Node>. and also its important to note that STL uses < for both insertion and find (i.e. count function uses <), so you can not use comparison based on cost for insertion and comparison based on state for finding (your code is like this!).

Upvotes: 1

Avinash
Avinash

Reputation: 13257

Thi is the typical example how you would you use std::set to find the element exists or not

#include <iostream>
#include <set>

int main(){
    std::set<int> mySet;
    mySet.insert(1);
    mySet.insert(2);
    mySet.insert(3);
    mySet.insert(4);
    mySet.insert(5);

    std::set<int>::iterator pos;
    pos = mySet.find(5);

    if ( pos == mySet.end()){
        std::cout << "Not Found" << std::endl;
    }
}

Complete example is as follows:

#include <iostream>
#include <set>

class Node {
public:
    Node(int _state =0, int _cost =0) : state(_state),cost(_cost) {}

    bool operator < (const Node& rhs) const {
        return cost < rhs.cost;
    }
private:
    int state;
    int cost;
};

int main(){
    std::set<Node> myset;
    myset.insert(Node(1,5));
    myset.insert(Node(2,6));
    myset.insert(Node(3,9));

    std::set<Node>::iterator pos, pos1;
    pos = myset.find(Node(1,5));
    pos1 = myset.find(Node(1,7));

    if ( pos == myset.end()){
        std::cout << "Not Found" << std::endl;
    } else {
        std::cout << "Found" << std::endl;
    }
    if ( pos1 == myset.end()){
        std::cout << "Not Found" << std::endl;
    } else {
        std::cout << "Found" << std::endl;
    }

}

Upvotes: 0

6502
6502

Reputation: 114461

It doesn't work because you declared a ser of pointers so that is what the container will compare.

Your comparison method < is not going to be used because std::set will use standard comparison between pointers. You will also find duplicates in your set if two Nodes have the same contente but a different address.

Upvotes: 0

fghj
fghj

Reputation: 9394

set<Node*> myset;

This is set of pointers; it calls operator== for pointers, not for Node.

You should use std::set<Node> if you want to see call of Node::operator==.

Upvotes: -2

Some programmer dude
Some programmer dude

Reputation: 409166

If you see for example this reference page, you see that there is a template parameter Compare. You have to implement your own comparison function.

Upvotes: 0

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385104

how does count in c++ stl set work?

It uses operator< by default.

In fact, in general, C++ Standard Library containers use !(a < b) && !(b < a) to determine the property of equivalence.

You can override the comparator used to perform this check by providing your own Compare template argument to the container type, though there is rarely a reason to — you should usually simply define operator< for your type instead, as you have done. (Make sure that it creates a Strict Weak Ordering, though.)

in my code, I declare a set like this --

set<Node*> myset;

after a few insertions, myset is like this {{1, 5}, {2, 6}, {3, 9}}

No, your set is never like this. Your set contains pointers, not Nodes. Make it a set<Node> instead.

Upvotes: 7

Related Questions