C++ how to sort vector<class *> with operator <
i have
class c1{
public:
int number;
开发者_StackOverflow中文版 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)
compares a c1
to a c1 *
- Your sort compares a c1 *
to a 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).
精彩评论