C++におけるラムダ式の話です。STLのアルゴリズムとからめて使うことが多いので、アルゴリズムとラムダ式をからめて説明します。
STLアルゴリズムもラムダ式もプログラミングをやる上で必須の技術ではありません。
しかし、使えるようになると技術の幅が広がります。コード行数が小さくなりますので不良も小さくなると思います。
詳しくはC++の聖書、ストラウストラップを参照ください。
STLアルゴリズムとラムダ式
STLでは80ものアルゴリズムが<algorithm>に定義されています。
まずは、どういう気持ちのときに使いたくなるかを説明していきます。
1,2,3,4,5の値が入った配列を考えます。
std::vector<int> v{1,2,3,4,5};
各値を2倍するにはどうしますか?for文を使えば簡単ですね。
for (int i=0; i<5; ++i){ v[i] *= 2; }
これをSTLアルゴリズムで書いてみます。今回はfor_eachを使ってみます。
multiplyTwo()という関数を定義して、for_eachを適用します。
void multiplyTwo(int& x){ x *= 2; } std::for_each(v.begin(), v.end(), multiplyTwo);
for_each(b, e, f)は[b:e)の全てのxについてf(x)を実行します。
上記でvの全ての要素にmultiplyTwoを実行することになります。
次に、multiplyTwo()ような関数をfor_eachのそばで定義したいと思ったとしましょう。
ここに登場するのがラムダ式です。
以下のように書きます。
std::for_each(v.begin(), v.end(), [](int &x){ x *= 2;});
multiplyTwoの部分が[](int &x){ x *= 2;}に代わりました。
なんとなく意味は分かると思います。[]がラムダ式だよという印です。あとはmultiplyTwoの定義のように書けばよいだけです。
このようにラムダ式はSTLアルゴリズムと一緒に使うことがほとんどです。STLアルゴリズムとラムダ式を一緒に覚えましょう。
ラムダ式を使うとコードがコンパクトにまとまっていい感じです。
少しだけSTLアルゴリズムとラムダ式を個々に説明します。
STLアルゴリズム
STLアルゴリズムは80もありますので全部覚えていられません。その時々で調べて使いましょう。
だいだいどういうのがあるのかを頭の片隅に置いておけばいいと思います。
- for_each系(シーケンスを変形しない)
- transform系(シーケンスを変形する)
- ソート、探索
- 最大値と最小値
for_each系(シーケンスを変形しない)
for_each(b, e, f)は[b:e)の全てのxについてf(x)を実行します。
fをいろいろ選ぶわけですが、その中でもよく使うものには名前が付いています。
- 述語 all_of, any_of, none_of
- 数える count, count_if
- 見つける find, find_if, find_if_not, find_first_of, adjacent_find, find_end
- 比較 equal, mismatch
- 探す search, search_n
transform系(シーケンスを変形する)
for_each系が引数のシーケンスを変形しませんが(要素の更新はある)、transformはシーケンス自身をいじっていきます。
- コピー copy, copy_if, copy_n, copy_backward, move, move_backward
- 重複排除 unique, unique_copy
- 削除 remove, remove_if, remove_copy, remove_copy_if, reverse, reverse_copy
- 入れ替え rotate, random_shuffle, partition
- 初期化 fill, generate
ソート、探索
シーケンスvの値間に順序がある場合、順序で小さい順に並べ替えることをソートといいます。
sort()が最小のメモリ量で最速の関数です。
sort()は同じ値の場合はどちらを先にするかが不定です。固定したい場合はstable_sort()を使います。
探索は普通はfind()を用いますが、ソート済であればbinary_search()が最適です。
最大値と最小値
最大値、最小値は
max(), min(), minmax()
を使用できます。minmax()はpairを返すので2回呼び出すのを省略できます。
ラムダ式
あまり複雑なことをしようと思わなければ、
[]で始めて普通に関数定義する
のがラムダ式と思っておいて間違いありません。
何となく一行で書くことが多いですが、複数行で書いても何も悪いことはありません。
あまり長いと普通に関数定義した方がいいんじゃない?と思いますが。
ローカル変数を使う
ラムダ式の中でローカル変数を使いたいときがあります。
※私はお薦めしません。非常に分かりづらい不良の元になりかねません。
[]の中に変数名を書きます。[var1, var2]
参照で使いたい場合は、&を付けます。[&var1, &var2]
混在もOKです。[var1, &var2]
また、すべてのローカル変数を使うときは[=]、すべてのローカル変数を参照として使うときは[&]です。
まとめ
C++のSTLアルゴリズムとラムダ式を説明しました。
コメント