The Super Programming Technique
§3.ラムダ式をC++で実現する【後編】
yaneSDK3rdのサンプル書いてたら、勢い余ってラムダプロセッサ作っちゃいましたよ!!
⇒ ダウンロードは、yaneSDK3rdのコーナーからどうぞ!
・ラムダプロセッサとは?
random_shuffleの第3パラメータとして関数オブジェクトを指定します。ところが、メンバ関数を関数オブジェクトにしようと思うと、
bind1st(mem_fun1_t<int,CApp,int>(CApp::myrand),this) |
のように、bind1stとmem_fun1_tと組み合わせる必要が出てきます。このへんが非常にめんどうくさい。さらに、そのあと関数をどこかに書かないといけません。別の関数にせずその場で、ささっと書くことはできんのか?というのが、ラムダプロセッサの製作動機です。
例) int (int x,int y) { return x+y; } |
と入力すれば、2数をとり、それを合計したものを返す関数オブジェクトを
作成します。(以下のように出力されます)
// lambdaクラスの定義 class lambda030416093804_0153 { public: int operator()(int x,int y) { return x+y; } }; // 関数オブジェクト(コピペして埋め込んでネ) lambda030416093804_0153() /** // 元ソース int (int x,int y) { return x+y; } */ |
↑のように出力されます。
この関数を用いて、
int c = lambda030416093804_0153()(10,25); |
とすれば、10+25で35がcに代入されます。
この関数オブジェクトの存在するスコープにある変数を、この関数オブジェクト内で 自由に用いることが出来ます。(コンストラクタで渡しているだけですが)
例) int (int r) { return pThis->Rand() % r; } CApp* pThis:this;; |
↑ CApp*型のpThisというメンバ。呼び出し元では、thisを引数として渡す。
(変換後のソース↓を参考にしてください)
ポインタの場合、CApp* のように書き、CApp
*とスペース等は入れないこと。
// lambdaクラスの定義 class lambda030416094214_7376 { public: lambda030416094214_7376(CApp* Arg1): pThis(Arg1){} int operator()(int r) { return pThis->Rand() % r; } protected: CApp* pThis; }; // 関数オブジェクト(コピペして埋め込んでネ) lambda030416094214_7376(this) /** // 元ソース int (int r) { return pThis->Rand() % r; } CApp* pThis:this; */; |
定数を加算するオブジェクトを生成する
int (int n) { return n+c; } int c; |
とすれば、コンストラクタで定数cをとる関数オブジェクトを生成します。
つまり、関数オブジェクトの出力が、
// 関数オブジェクト(コピペして埋め込んでネ) lambda030416094701_3931(c) |
このようになります。
int (int n) { return n+c; } int c:c2; |
こう書けば、コンストラクタで定数c2をとる関数オブジェクトを生成します。
// 関数オブジェクト(コピペして埋め込んでネ) lambda030416094734_1538(c2) |
コンストラクタの引数は無限に書けます。
int () { return a+b+c+d; } int a; int b; int c; int d; ine e; |
と書けば
// lambdaクラスの定義 class lambda030416094958_2421 { public: lambda030416094958_2421(int Arg1,int Arg2,int Arg3,int Arg4,int Arg5): a(Arg1),b(Arg2),c(Arg3) ,d(Arg4),e(Arg5){} int operator()() { return a+b+c+d+e; } protected: int a; int b; int c; int d; int e; }; // 関数オブジェクト(コピペして埋め込んでネ) lambda030416094958_2421(a,b,c,d,e) /** // 元ソース int () { return a+b+c+d+e; } int a; int b; int c; int d; int e; */ |
と出力されます。
型名で、constとか参照とかポインタに対応しました。配列はできません。ゴメンナチイ..
⇒ constと参照とポインタに対応しますた。(サンプル7b)