テンプレートを使う練習をかねて、構造体のメンバ変数同士を比較してソートしてみます。
#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を使えればなぁ。
0 件のコメント:
コメントを投稿