C++ std::set comparator

2019-07-18 20:08发布

问题:

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:

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).



回答2:

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



回答3:

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;
    }
};