Reputation: 859
I am pushing stuff into a priority Queue and I've made a comparison method for elements that go in there , when I checked the order , I realized I wanted elements to go in the other way around , so I went and changed all the boolean returns from my comparison method to be opposite of what they originally were and now it gives me a million assertion failures. If I ignore them , the program still works as expected , but why the assert fails ? Why should the program care ?
bool operator()(charElement &operand1,charElement &operand2)
{
// If the frequency of op1 < op2 then return true
if(operand1.i_frequency < operand2.i_frequency) return true; //change to false
// If the frequency of op1 > op2 then return false
if(operand1.i_frequency > operand2.i_frequency)return false; //change to true
// If the frequency of op1 == op2 then return true (that is priority is indicated to be less even though frequencies are equal)
if(operand1.i_frequency == operand2.i_frequency)return true; //change to false
// By default , return true (that is priority is indicated to be less)
return true; //change to false
}
By the way, why was my query downvoted ? I try to ask sane questions and I believe this is one of them.
Specifics : I changed the operator definition to what @sehe suggested. Now if I add a not operator to the return value, it gives me assertion failures (invalid operator<) inside the include file , line number 2457. I checked the file , it seems that the error is in an inline method called Push_heap_0 , but I am stumped as to what that code does
Upvotes: 0
Views: 1376
Reputation: 263098
Can't you simply reverse the order of the parameters? That is, replace:
bool operator()(charElement &operand1,charElement &operand2)
with:
bool operator()(charElement &operand2,charElement &operand1)
Then you can leave the body of the function as it is.
On a side note, comparisons are read-only operations, and we should always respect const correctness:
bool operator()(const charElement& operand2, const charElement& operand1)
Also, you are not allowed to return true
if the elements are equal:
if(operand1.i_frequency == operand2.i_frequency)return true; // HUGE PROBLEM!
You must always return false
in that case, no matter if you want "normal" or "backwards" order.
The opposite of <
is not >
, but >=
. This seems to be hard for programmers to grasp.
Upvotes: 4
Reputation: 392893
The problem could be many things
That said, it looks like you can greatly simplify your comparator. My preferred idiom for this
bool operator()(charElement &operand1,charElement &operand2)
{
return operand1.i_frequency < operand2.i_frequency;
}
or for reverse logic:
bool operator()(charElement &operand1,charElement &operand2)
{
return operand1.i_frequency > operand2.i_frequency;
}
If it is actually a compound and a little more complex:
bool operator()(charElement &operand1,charElement &operand2)
{
return std::tie(operand1.i_frequency, operand1.otherfield) <
std::tie(operand2.i_frequency, operand2.otherfield);
}
Upvotes: 1