Reputation: 811
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
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
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
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 Node
s have the same contente but a different address.
Upvotes: 0
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
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
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 Node
s. Make it a set<Node>
instead.
Upvotes: 7