在 C++ 中,您可以使用类似的仿函数boost::bind
来很好地完成这项工作:
#include <vector>
#include <algorithm>
struct pkt {
double x;
double y;
double alfa;
pkt(double x, double y, double alfa)
:x(x), y(y), alfa(alfa) { }
};
int main() {
std::vector<pkt> p;
p.push_back(pkt(10., 0., 20.));
p.push_back(pkt(10, 0., 30.));
p.push_back(pkt(5., 0., 40.));
std::sort(p.begin(), p.end(),
boost::bind(&pkt::alfa, _1) < boost::bind(&pkt::alfa, _2) ||
boost::bind(&pkt::alfa, _1) == boost::bind(&pkt::alfa, _2) &&
boost::bind(&pkt::x, _1) < boost::bind(&pkt::x, _2));
}
如果您需要多次执行此操作,您还可以通过创建一个接受成员指针并进行排序的函数对象来解决问题。您可以将它重用于任何类型的对象和成员。首先你如何使用它:
int main() {
/* sorting a vector of pkt */
std::vector<pkt> p;
p.push_back(pkt(10., 0., 20.));
p.push_back(pkt(5., 0., 40.));
std::sort(p.begin(), p.end(), make_cmp(&pkt::x, &pkt::y));
}
这是 make_cmp 的代码。随意撕掉它(使用boost::preprocessor
):
#include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
// tweak this to increase the maximal field count
#define CMP_MAX 10
#define TYPEDEF_print(z, n, unused) typedef M##n T::* m##n##_type;
#define MEMBER_print(z, n, unused) m##n##_type m##n;
#define CTORPARAMS_print(z, n, unused) m##n##_type m##n
#define CTORINIT_print(z, n, unused) m##n(m##n)
#define CMPIF_print(z, n, unused) \
if ((t0.*m##n) < (t1.*m##n)) return true; \
if ((t0.*m##n) > (t1.*m##n)) return false; \
#define PARAM_print(z, n, unused) M##n T::* m##n
#define CMP_functor(z, n, unused) \
template <typename T \
BOOST_PP_ENUM_TRAILING_PARAMS(n, typename M)> \
struct cmp##n { \
BOOST_PP_REPEAT(n, TYPEDEF_print, ~) \
BOOST_PP_REPEAT(n, MEMBER_print, ~) \
cmp##n(BOOST_PP_ENUM(n, CTORPARAMS_print, ~)) \
BOOST_PP_IF(n, :, BOOST_PP_EMPTY()) \
BOOST_PP_ENUM(n, CTORINIT_print, ~) { } \
\
bool operator()(T const& t0, T const& t1) const { \
BOOST_PP_REPEAT(n, CMPIF_print, ~) \
return false; \
} \
}; \
\
template<typename T \
BOOST_PP_ENUM_TRAILING_PARAMS(n, typename M)> \
cmp##n<T BOOST_PP_ENUM_TRAILING_PARAMS(n, M)> \
make_cmp(BOOST_PP_ENUM(n, PARAM_print, ~)) \
{ \
return cmp##n<T BOOST_PP_ENUM_TRAILING_PARAMS(n, M)>( \
BOOST_PP_ENUM_PARAMS(n, m)); \
}
BOOST_PP_REPEAT(CMP_MAX, CMP_functor, ~)
#undef TYPEDEF_print
#undef MEMBER_print
#undef CTORPARAMS_print
#undef CTORINIT_print
#undef CMPIF_print
#undef PARAM_print
#undef CMP_functor