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)


戻る