自分のメンバ関数をtransform()とかに渡す
方法を探していたら、cppllのML過去ログから発見!
http://ml.tietew.jp/cppll/cppll/article/8913
・・・2003年、「思兼」って俺だなぁ。こんなコメントした覚えあるなぁ。
とりあえずサンプル.
#include <vector> #include <algorithm> #include <functional> struct Hoge { using namespace std; size_t foo(size_t x) const { return t_[x]; } vector<size_t> bar() { vector<size_t> before; // beforeに何か入る. vector<size_t> after; transform(before.begin(), before.end(), back_inserter(after), bind1st(mem_fun(&Hoge::foo), this)); return after; } private: size_t t_[N]; };
で、今回の罠は、fooをそのままmem_funに渡せなくて、&Hoge::fooって書かないといけないこと。
そんなしょうもない罠に引っかかるくらいだったら、最初っからtransform使わないで、
for (size_t i = 0; i < before.size(); ++i) { after.push_back(foo(before[i])); }
と書けば良かった。
もちろん、今回はtransformだったから後者の方が簡単というだけで、これがもっと複雑なアルゴリズムだと手で実装するよりもきちんと関数オブジェクトを作った方がいいんだけどね。
でも、 bind1st(mem_fun(bar), this) しなくても bar を size_t (size_t) な関数オブジェクトとして値渡しにできる言語を使えば最初から何も問題ないわけで、やっぱりオブジェクト指向と関数型のハイブリッド言語がこれからの主流になるべきだと思う。
C++の関数型っぽさはGenericsによる模倣であって、言語レベルで関数型パラダイムに対応していないのが、C++で関数型プログラミングをするときの障害になっている。