tags:

views:

928

answers:

3

This is the code:

struct comp
{
 bool operator()(Reputation *one, Reputation *two)
 {
  if (one->Amount < 0 && two->Amount >= 0)
   return false;
  if (one->Amount >= 0 && two->Amount < 0)
   return true;

  if (one->Amount >= 0)
   return one->Amount <= two->Amount;
  else
   return one->Amount >= two->Amount;
 }
};

And this is the problem:

Debug Assertion Failed!
File: ..\VC\include\xtree
Line: 638

Expression: invalid operator<

After that, I can choose "Abort", "Retry" or "Ignore". If I choose ignore many more (identical ones) come up but it ends up working perfectly.

The problem seems to occur when I insert a Reputation with ->Amount == to one of the Reputation *'s previously inserted, but I'm not sure about this last one.

Any help would be greatly appreciated

EDIT: The order I want them ordered in is first the positive ones in asc order, then the negative ones in desc order. Example: 1 5 10 11 11 20 50 -1 -5 -50

+1  A: 

The items in the std::set must be unique! (and less-comparable) If you want to have multiple items with the same value (like the sample you provided) use std::multiset.

see: http://www.cppreference.com/wiki/stl/set/start and http://www.cppreference.com/wiki/stl/multiset/start

Kasprzol
I converted it to std::multiset, but the same exact problem occurs.
Andreas Bonini
A: 

You can't insert same values into std::set, it requires unique values. Use std::multiset.

For your funny ordering this seems to work:

struct comp
{
    bool operator()(const Reputation *a, const Reputation *b)
    {
        if (a->Amount < 0 && b->Amount < 0)
            return a->Amount > b->Amount;
        else if (a->Amount < 0) return false;
        else if (b->Amount < 0) return true;
        else return a->Amount < b->Amount;
    }
};
stefanB
The set is a set of pointers. They are all unique, even if some have the same ->Amount.This is the exact code: multiset<Reputation *, comp> sorted; for (Reputation *rep = Reputation::GetReputationTable(); rep->Id; ++rep) sorted.insert(rep);
Andreas Bonini
Oh ok, it wasn't clear from the example ... but yeah if you store pointers use pointers
stefanB
+5  A: 

You must define a relation that's irreflexive, just like < -- therefore, change the <= to < and the '>=' to '>' in the last couple of comparisons in your method. This is what VC++ is diagnosing.

Moreover, given a correctly coded, <-like operator, if two items a and b are such that a < b and b < a are both false, those items are considered equivalent and thus only one will be inserted in the set (it's not material whether the items could be distinguished by some other comparison: only the equivalence relationship implied by the comparator matters).

Alex Martelli
Thank you, that fixed it. Much appreciated!
Andreas Bonini
Glad I helped fix the "debug assertion failed" issue, but please do read my latest edit about "uniqueness" -- you do need a multiset, like @Kasprzol says, if you want to keep multiple items that are not distinguishable _by the comparator_.
Alex Martelli
Yes, I already converted it to a multiset as well following Kasprozl's advice!
Andreas Bonini