2007-12-23-02-Lambda ! なんて素敵なラムダ! - project-enigma

2007-12-23-02-Lambda ! なんて素敵なラムダ!

>> Site top >> weblog >> 月別アーカイブ >> 2007年12月のlog >> 2007-12-23-02-Lambda ! なんて素敵なラムダ!

最終更新日付:2014/01/02 00:00:00


Lambda ! なんて素敵なラムダ!

2007 年 12 月 23 日

リリースの準備をあらかた済ませ、本当に久しぶりに 「 何者にも追われていない時間」 を今日は楽しんでいる。リリースしてしまえば、次の作品に取り憑かれ、追われるような生活が戻ってくるのは目に見えている。だから、今日・明日くらいはのんびりするのだ...と、久しぶりにこの本を読み返している。

ともすれば熱狂的な信者のように、陰郎は C++ 言語を作った Bjarne Stroustrup 教授の哲学が好きだ。だが Palmware 開発を、とりわけ ARMlet を中心とした開発をするにつれ、本来の意味での C++ から離れてしまっているため、ここらで読み返してみようと思ったわけだ。

読み始めてすぐ、第 -1 章の xx ページでなんとも面白いものが目に飛び込んできた。おそらく以前は読み飛ばしてしまったのだろう。先へ読み進めたい気持ちを抑えながら前書きを読むときには往々にしてやってしまうものだ。そこには、STL アルゴリズムにファンクタを渡す際に表記が劇的に簡潔になる Lambda クラスの例示があった。何が面白いのか、順を追ってみていこう。

通常、シーケンスの中から 「 ある値を超える最初の要素 」 を見つける場合、ファンクタ greater をアダプタ binder2nd と組み合わせる。つまり、以下のように。

const int v[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const int* p = find_if( v, v + 10, bind2nd( greater<int>( ), 6 ) );

問題は、bind2nd( greater<int>( ), 6 ) という部分が直感的に分り難いということだ。find_if 関数テンプレートは unary_function を要求するため、binary_function であるgreater の第2パラメータを 6 でバインドした binder2nd を得るために bind2nd 関数テンプレートを使っている。それは読めばわかるし、仕様からも明らかだ。しかし、読まなければわからない。ひとめ見て直感的に理解出来る方が望ましい。

この問題を解決する、目の醒めるようなのが書かれていたのだ。最終的な答えを先に書くと、以下のようになる。

Lambda x;
p = find_if( v, v + 10, x > 6 );

これはもう、表記上はほとんど文句のつけようがない。背後にあるカラクリもそれほど難しいものでもない。要は、x > 6 が binder2nd( greater<int>(), 6 ) を返せば良い。そのために必要なのは以下の Lambda クラスと演算子オーバーロードが1つだけである。

class Lambda{ };
 
template<class T>
binder2nd< greater<T> > operator> ( Lambda, const T& v ) {
    return bind2nd( greater<T>( ), v );
};

Lambda クラスは空っぽ。そして演算子オーバーロードも簡潔だ。これにより、期待した通りのことが起こる。先のややこしい記述とやっていることは同じだ。効率も変わらない。STL の理念どおり、すべてはコンパイル時に解決される。素敵だ。素敵だよ Lambda!

とはいえ、現実のプログラミングではなかなかこのようなシンプルな例にはお目にかからない。しかし、こういった素敵なアイデアがあるだけでもプログラミングは楽しくなる。今日は良い日だった。

 

コメント

このページにコメントする

 

このページのタグ

Page tag : 開発

 

 


Copyright(C) 2005-2017 project-enigma.
Generated by CL-PREFAB.