Reputation: 1133
I would like to modify the following code so that I can sort using objects. The current code is fine when sorting individual methods that return a single value. How can I implement using methods that returns a object;
template<typename T, typename M, template<typename> class C = std::less>
struct method_comparer : std::binary_function<T, T, bool>
{
explicit method_comparer(M (T::*p)() const) : p_(p) { }
bool operator ()(T const& lhs, T const& rhs) const
{
return C<M>()((lhs.*p_)(), (rhs.*p_)());
}
private:
M (T::*p_)() const;
};
template<typename T, typename M>
method_comparer<T, M> make_method_comparer(M (T::*p)() const)
{
return method_comparer<T, M>(p);
}
template<template<typename> class C, typename T, typename M>
method_comparer<T, M, C> make_method_comparer2(M (T::*p)() const)
{
return method_comparer<T, M, C>(p);
}
Main.cpp
// works well
std::sort(vec_p2d.begin(),vec_p2d.end(),make_method_comparer(&Point2D::getX));
// Would like to implement this
std::sort(vec_l2d.begin(),vec_l2d.end(),make_method_comparer(&Line2D::getPt1));
getPt1() methods return a Point2D object which contains the values for int x and int y;
Upvotes: 0
Views: 188
Reputation: 74048
AFAICS, you can leave your code as is. The only thing you must define is a comparison operator for Point2D
or whatever object you're returning:
class Point2D {
public:
friend bool operator<(const Point2D &p1, const Point2D &p2) { ...; }
...
};
You can also remove your method_comparer
class and just give appropriate comparer functions to sort:
bool compare_line_points(const Line2D &l1, const Line2D &l2) {
return l1.getPt1() < l2.getPt1();
}
and
std::sort(vec_l2d.begin(), vec_l2d.end(), compare_line_points);
Depending on your requirements, these are just a bunch of one- or two-liners. No need for templates.
Upvotes: 1
Reputation: 4291
If you may use boost, how about:
std::sort(vec_p2d.begin(), vec_p2d.end(), boost::bind( &Point2D::getX, _1 ) < boost::bind( &Point2D::getX, _2 ) );
&
std::sort(vec_p2d.begin(), vec_p2d.end(), boost::bind( &Point2D::getPt1, _1 ) < boost::bind( &Point2D::getPt1, _2 ) );
?
Upvotes: 1