メンバー関数にもとづいてソートする
「オブジェクトの状態に依存したソートを行いたい」ということがあると思います。
#include <vector> using namespace std; class A { public: A(int k); vector<int> sorted(); private: vector<int> vec; int param; }; A::A(int k) { param = k; } vector<int> A::sorted() { // paramに依存したソートをして返す }
そこでメンバー関数をsort
の比較関数に使う方法として
bind
関数を使う方法- 関数オブジェクトを定義する方法
の2つを紹介したいと思います。 (後続のコードのうち既出のコードと重複する部分を適宜省略します。)
1. bind
関数を使う方法 (C++11以降)
#include <function> // bind using namespace std::placeholders; class A { private: bool cmp(int a, int b); } vector<int> A::sorted() { vector<int> ret = vec; sort(ret.begin(),ret.end(),bind(&A::cmp,this,_1,_2)); return ret; } bool A::cmp(int a, int b) { return a%param < b%param; }
考えてみればparam
もbind
を使って渡せるのでcmp
が2引数である必要もないですね。
2.関数オブジェクトを明示的に定義する方法
比較のためのクラスcmp
を定義し、関数呼び出し演算子()
をオーバーロードします。
class A { private: class cmp { public: A &a; cmp(A &a) : a(a) {}; bool operator() (int x, int y) { return x%a.param < y%a.param; }; }; }; vector<int> A::sorted() { vector<int> ret = vec; sort(ret.begin(),ret.end(),cmp(*this)); return ret; }
とくに前者のような関数型のアプローチは適用範囲が広そうなので、覚えておいて損はないと思います。