テンプレートを使う練習をかねて、構造体のメンバ変数同士を比較してソートしてみます。
#include <iostream> #include <iomanip> #include <algorithm> #include <string> using namespace std; /* メンバ変数同士を比較するためのクラス */ template <typename T, typename Elem> class MemberComp { private: Elem T::* e; public: MemberComp(Elem T::* e) { this->e = e; }; bool operator()(const T &a, const T&b) { return a.*e < b.*e; }; }; template <typename T, typename Elem, typename Nest> class NestedMemberComp { private: Nest T::* nest; Elem Nest::* e; public: NestedMemberComp(Nest T::* nest, Elem Nest::* e) { this->nest = nest; this->e = e; }; bool operator()(const T &a, const T&b) { return a.*nest.*e < b.*nest.*e; }; }; /* インスタンス作成時に型名を省略するための関数 */ template<typename T, typename Elem> MemberComp<T, Elem> make_comp(Elem T::* e) { return MemberComp<T, Elem>(e); } template<typename T, typename Elem, typename Nest> NestedMemberComp<T, Elem, Nest> make_comp(Nest T::* nest, Elem Nest::* e) { return NestedMemberComp<T, Elem, Nest>(nest, e); } /* 比較対象の構造体 */ struct Data { int a; double b; struct _c { int d; } c; }; void print_data(Data *t, int n) { for (int i = 0; i < n; ++i) { cout << t[i].a << ", " << setprecision(2) << setiosflags(ios::fixed) << t[i].b << ", " << t[i].c.d << endl; } } int main(void) { Data target[3] = {{0, 1.5, {3}}, {1, 3.0, {2}}, {2, 2.0, {1}}}; print_data(target, 3); cout << "b でソート" << endl; std::sort(target, target + 3, make_comp(&Data::b)); print_data(target, 3); cout << "c.d でソート" << endl; std::sort(target, target + 3, make_comp(&Data::c, &Data::_c::d)); print_data(target, 3); // lambda式を使える場合 cout << "lambda式を使って b でソート" << endl; std::sort(target, target + 3, [](const Data &a, const Data &b) { return a.b < b.b; }); print_data(target, 3); return 0; }
実行結果
0, 1.50, 3 1, 3.00, 2 2, 2.00, 1 b でソート 0, 1.50, 3 2, 2.00, 1 1, 3.00, 2 c.d でソート 2, 2.00, 1 1, 3.00, 2 0, 1.50, 3 lambda式を使って b でソート 0, 1.50, 3 2, 2.00, 1 1, 3.00, 2
lambda式を使えると楽で良さそう。C++11を使えればなぁ。