C++11 ラムダ関数を利用してみる
C++のSTLを使うときに毎回iteratorで回していた部分があって、毎回面倒であった。
そこで今更であるが、C++11で採択されたラムダ関数の使い方/使い道を調べ、少しだけ分かった気がするのでまとめておく。
【ラムダ関数を使う理由】
std::sortやstd::for_each等の最後の引数に関数オブジェクトを渡すために、これらの関数の直前に関数オブジェクトを書くことが多かった。
しかしこれらの呼び出しの前に、struct{... void operator() ...}のように毎回関数オブジェクトを定義するのは面倒であるし、コードの記述量が増えてソースコードの処理の流れが分かりづらくなる。
ラムダ関数を利用することで、これらの問題を解消することが出来る。
※std::sortやstd::for_eachの第3引数に関数ポインタを使うべきではない理由については、以下または、Effective STLの「第46項 アルゴリズムのパラメータとして関数の代わりに関数オブジェクトの使用を考えよう」を参照のこと。
http://d.hatena.ne.jp/mickey24/touch/searchdiary?word=*%5BC%2B%2B%5D
【使い方】
実際のラムダ関数の使い方を以下に示す。
1. 基本形
※基本形という表現が正しいのかについては置いておく。
std::list < int > l; l.push_back( 3 ); l.push_back( 5 ); std::for_each( l.begin(), l.end(), []( int v ){ std::cout << v << std::endl; } );
[プログラムの実行結果]
3 5
std::listに保存されている値が全て表示される。
2. ラムダ関数内部で特定の変数を利用したい時
std::list < int > l; int n = 10; l.push_back( 3 ); l.push_back( 5 ); std::for_each( l.begin(), l.end(), [n]( int v ){ std::cout << n << std::endl; } );
[プログラムの実行結果]
10 10
変数nの値がstd::listの要素数分だけ出力される。
3. ラムダ関数内部でクラスのメンバ変数利用したい時
class Hoge { int m_Foo; public: void Piyo(); }; void Hoge::Piyo() { std::list < int > l; m_Foo = 100;; l.push_back( 3 ); l.push_back( 5 ); std::for_each( l.begin(), l.end(), [this]( int v ){ std::cout << m_Foo << std::endl; } ); } int main() { Hoge h; h.Piyo(); return 0; }
[プログラムの実行結果]
100 100
メンバ変数m_Fooの値がstd::listの要素数分だけ出力される。
他にもラムダ関数に関してはいろいろあるようだが、現在使っているのは上記3つのパターン。
まだ使いこなしていないが、ラムダ関数のおかげでソースコードが非常に簡潔になった。
今後、他の場合について利用することがあれば、追加していきたいと思う。
[参考文献]
- Effective STL 「第46項 アルゴリズムのパラメータとして関数の代わりに関数オブジェクトの使用を考えよう」
- http://d.hatena.ne.jp/wordi/20120108/p1
- http://d.hatena.ne.jp/gintenlabo/20130516/1368711542
- http://d.hatena.ne.jp/mickey24/touch/searchdiary?word=*%5BC%2B%2B%5D