如何使用结构和比较函数向量的std :: sort?

感谢在C中的解决scheme ,现在我想在C ++中使用std :: sort和vector来实现:

typedef struct { double x; double y; double alfa; } pkt; 

vector< pkt > wektor; 用push_back()填充; 比较function:

 int porownaj(const void *p_a, const void *p_b) { pkt *pkt_a = (pkt *) p_a; pkt *pkt_b = (pkt *) p_b; if (pkt_a->alfa > pkt_b->alfa) return 1; if (pkt_a->alfa < pkt_b->alfa) return -1; if (pkt_a->x > pkt_b->x) return 1; if (pkt_a->x < pkt_b->x) return -1; return 0; } sort(wektor.begin(), wektor.end(), porownaj); // this makes loads of errors on compile time 

什么是纠正? 在这种情况下如何正确使用std :: sort?

std::sort使用与qsort中使用的不同的比较函数。 这个函数不是返回-1,0或者1,而是返回一个bool值,表示第一个元素是否小于第二个元素。

你有两个可能性:实现operator <你的对象; 在这种情况下,没有第三个参数的默认sort调用将起作用; 或者你可以重写你的上面的函数来完成同样的事情。

注意你必须在参数中使用强types。

另外,根本不用这个函数。 而是使用一个函数对象。 这些从内联中受益。

 struct pkt_less { bool operator ()(pkt const& a, pkt const& b) const { if (a.alfa < b.alfa) return true; if (a.alfa > b.alfa) return false; if (ax < bx) return true; if (ax > bx) return false; return false; } }; // Usage: sort(wektor.begin(), wektor.end(), pkt_less()); 

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

如果你需要这么多次,你也可以通过创build一个接受成员指针的函数对象来解决这个问题。 你可以重用它的任何types的对象和成员。 首先你如何使用它:

 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 

使用C ++ 0x和lambdas Konrad的解决scheme如下所示:

 sort(wektor.begin(), wektor.end(), [](pkt const& a, pkt const& b) { if (a.alfa < b.alfa) return true; if (a.alfa > b.alfa) return false; if (ax < bx) return true; if (ax > bx) return false; return false; });