简体   繁体   中英

C++ how to sort vector<class *> with operator <

i have

 class c1{

public:
    int number;

    c1()
    {
        number=rand()%10;
    }

    bool operator < (c1 *w)
    {
        return number < w->number;
    }


};

vector<c1*> vec = { ... }
sort(vec.begin(),vec.end()) 

why it dosent sort ?

but if we had

 bool operator < (c1 w)
    {
        return number < w.number;
    }

and

vector<c1> vec = { ... }

it would have been sorted !

The most straightforward approach is to define a function

bool c1_ptr_less( c1 const *lhs, c1 const *rhs ) {
    return lhs->something < rhs->something;
}

std::sort( vec.begin(), vec.end(), & c1_ptr_less );

What I would suggest is a generic functor to take care of all pointer arrays

struct pointer_less {
    template< typename T >
    bool operator()( T const *lhs, T const *rhs ) const
        { return * lhs < * rhs; }
};

std::sort( vec.begin(), vec.end(), pointer_less() );

Armed with this, define the usual c1::operator< ( const c1 & ) and likewise for other classes.

Generally, best practice is to avoid pointers entirely, including arrays of pointers.

To answer your title question, you can't.

Pointers are built-in types, you cannot override operators where all operands are built-in types.

Luckily, there's an overload of std::sort that allows you to specify a comparison function (or functor) so the operator< isn't used.

bool operator < (c1 *w)c1c1 *进行比较c1 * - 您的排序将c1 *c1 *进行比较c1 *

You need to pass a compare function to std::sort :

bool compare_c1 (c1* x, c1* y)
{
  return *x < y;
}

std::sort(v.begin(), v.end(), compare_c1);

Or if you are using GCC >= 4.5 or Visual Studio 2010 (I'm do not know sure about Intel compiler) you can use lambdas (they are part of the C++0x standard):

std::sort(v.begin(), v.end(), [] (c1* x, c1* y) { return *x < y; });

Add a external operator< and keep de original one:

bool operator<(c1* a, c1* b) { return *a < *b; } 

Now sort will work on the vector.

phimuemue's answer sums it up, I'll just add that, as a workaround, you can create a wrapper class that contains only one member - a pointer to c1, and then overload its operator <. Then you could sort a vector of object of that class.

And in your example, vector<c1*> is sorted. Just not to the criteria you seem to want: by default, sort uses std::less<T> as the ordering criteria, and std::less<ci*> compares the pointers (which is what you'd expect). If you don't want the default criteria, then you have to pass a third argument to sort , a predicate defining the ordering you want.

And of course, your member operator<(c1*) will only be called when you compare a c1 with a ci* (and only if the c1 is an rvalue). Such operators are very, very rare---normally, both sides of a < operator should take the same type (and should be const , since a < operator which modifies the values of the objects it compares would be surprising, to say the least).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM