ページ 1 / 1
listでのクラスのメンバ変数のソート
Posted: 2010年11月15日(月) 21:52
by bbcs
どうも。毎回STLについて質問させていただいてます
今回もSTLについてです。
STLのlistにおいて、クラスのメンバ変数についてソートしたいのですが
調べてみてもよく分かりません・・・
演算子のオーバーロードが必要とか何とかで全く分かりません
2つほど質問があるので、回答をお願いします
質問1
class A
{
public:
int a;
A(int _a){a = _a}
}
というクラスがあるとして、クラスAのメンバ変数aについてソートする方法を教えてください。
質問2
今回の質問に関して別の話としてですが、
演算子のオーバーロードをする必要性と
演算子のオーバーロードをすることのメリットを教えてください
よろしくお願いします
Re:listでのクラスのメンバ変数のソート
Posted: 2010年11月16日(火) 01:02
by めるぽん
>クラスAのメンバ変数aについてソートする方法を教えてください。
大きく2通りの方法があります。
一つは、A の operator< を定義してソートする方法です。
class A; // ↑の定義の通り
bool operator<(const A& lhs, const A& rhs) {
return lhs.a < rhs.a;
}
int main() {
std::list<A> list;
list.push_back(A(2));
list.push_back(A(3));
list.push_back(A(1));
list.sort(); // 1 2 3
}
もう一つはファンクタを指定する方法です。
class A; // ↑の定義の通り
// ファンクタを作ってソート
struct pred {
bool operator()(const A& lhs, const A& rhs) const {
return lhs.a < rhs.a;
}
};
int main() {
std::list<A> list;
...
list.sort(pred()); // 1 2 3
}
// 別に関数ポインタでも構わない
bool pred2(const A& lhs, const A& rhs) {
return lhs.a > rhs.a; // 降順にしてみる
}
int main() {
std::list<A> list;
...
list.sort(pred2); // 3 2 1
}
クラス A 自体に順序を持たせたい場合は最初の方法を使って、ソートする際に順序を決めたい場合は2番目の方法を使えばいいと思います。
もちろん両方の方法を混ぜて使うこともできます。
Re:listでのクラスのメンバ変数のソート
Posted: 2010年11月16日(火) 01:04
by めるぽん
>演算子のオーバーロードをする必要性
他のライブラリが、今回みたいに < で比較できることを要求していて、ファンクタを取る関数が用意されていない場合は、必須になりますね。
ただ、演算子オーバーロードはむやみに使うと意味が分からなくなるので、ある本では「本当に演算子オーバーロードを使うのが正しいと確信できる場合以外は使わないこと」みたいに書いていたはずです。
>演算子のオーバーロードをすることのメリット
正しく演算子オーバーロードが使われたプログラムである場合、コードが読みやすくなります。
それから、
template<class T>
T abs(T v) {
v < 0 ? -v : v;
}
みたいなコードを書いたとき、これは組み込み型だけでなく、operator< と単項 operator- が定義されたクラスでも受け取ることができます。
もし演算子オーバーロードが無かった場合、
template<class T>
T abs2(T v) {
v.less(0) ? v.negate() : v;
}
みたいなコードを別に書くことになるでしょう。
Re:listでのクラスのメンバ変数のソート
Posted: 2010年11月16日(火) 19:16
by bbcs
めるぽんさん、丁寧な回答ありがとうございます
思ったとおりの事ができました
これでだいぶ進歩できそうです
本当にありがとうございました