I am learning how to write the comparator in C . At first time, I return num1<num2
, as a result I get a set in ascending order. Then I return num1>num2
and I get a set in descending order. Now I try to return num1-num2
which should equal to num1>num2
in my opinion, I get a set in descending order as predicted. But when I try to return num2-num1
, I still get a set in descending order. How could it happen? Is there any difference between return num2-num1
and return num1<num2
?
#include <iostream>
#include <set>
using namespace std;
struct myCmp{
bool operator()(const int& num1, const int& num2){
return num2-num1;
}
};
int main()
{
set<int,myCmp> st;
st.insert(1);
st.insert(2);
st.insert(3);
for(auto it=st.begin();it!=st.end();it ){
cout<<*it<<endl;
}
return 0;
}
CodePudding user response:
I try to return
num1-num2
which should equal tonum1>num2
in my opinion
Let's try that:
num1 = 5;
num2 = 10;
num1>num2 // false
num1-num2 // -5, true
So, no, your assumption is incorrect. All results when num1 != num2
are converted to true
in a boolean context, and only when num1 == num2
will the result be converted to false
.
CodePudding user response:
Now I try to return
num1-num2
which should equal tonum1>num2
in my opinion
That is incorrect.
Is there any difference between
return num2-num1
andreturn num1<num2
?
Yes.
num2-num1
returns an integer value that is the result of subtracting the value of num1
from the value of num2
. Since your comparator returns a bool
, a result of 0
will be converted to false
, and any other result will be converted to true
.
num1<num2
returns a boolean value specifying whether or not num1
is actually less-than num2
. Any value of num1
that is less-than the value of num2
will return true
, all other values will return false
.
So, as you can see, both approaches return completely different things.
std::set
has the following requirement:
std::set
is an associative container that contains a sorted set of unique objects of typeKey
. Sorting is done using the key comparison functionCompare
. Search, removal, and insertion operations have logarithmic complexity. Sets are usually implemented as red-black trees.Everywhere the standard library uses the
Compare
requirements, uniqueness is determined by using the equivalence relation. In imprecise terms, two objectsa
andb
are considered equivalent if neither compares less than the other:!comp(a, b) && !comp(b, a)
.
Using return num1<num2
(or return num1>num2
) satisfies that requirement, but return num2-num1
breaks it.
For example, let's assume a = 1
and b = 2
.
Using num1<num2
, you get the following:
!comp(a, b) && !comp(b, a)
= !comp(1, 2) && !comp(2, 1)
= !(1 < 2) && !(2 < 1)
= !true && !false
= false && true
= one is less-than the other, so not equal, which is correct!
Using num1>num2
, you get the following:
!comp(a, b) && !comp(b, a)
= !comp(1, 2) && !comp(2, 1)
= !(1 > 2) && !(2 > 1)
= !false && !true
= true && false
= one is less-than the other, so not equal, which is correct!
Using num2-num1
, you get the following:
!comp(a, b) && !comp(b, a)
= !comp(1, 2) && !comp(2, 1)
= !(2 - 1) && !(1 - 2)
= !(1) && !(-1)
= !true && !true
= false && false
= neither is less-than the other, so equal, which is incorrect!