ラムダ式やラムダ関数として使われるラムダ、
そもそもラムダ自体の意味ってなんだろう?とまず疑問が浮かぶはず。ラムダとは「無名」や「匿名」と言った意味を持ちます。つまりラムダ関数は無名関数となりますね。無名とは想像の通りです、今までは関数を作成する際には必ず関数名が必要でしたがそれが必要なくなったということです。その他ラムダを使うことによって可読性や生産性、パフォーマンスの向上が見込めます。
しかし、C++をある程度やっている人などでない限り最初からラムダの使い所がきっちりわかる人なんていません。そこでここではラムダがどのように便利なのかとその使用方法について紹介します。まずは書き方から。
#include <iostream> using namespace std; void main(){ //ラムダ式の構文 []()->{}; /* [] キャプチャ (= or & を[]に入れる) () 引数 -> 戻り値の型 {} 関数の処理本体 */ }
このよくわからない記号だらけの構文がラムダ式でコンパイル時にラムダ式に相当する関数オブジェクトを作成してくれます。
まず"[]"の中身は"="または"&"が入りますがなにを入れるかは"{}"内の処理をどのようにするかで決まります。"()"の引数の部分はいつもの関数作成の時と同じで"->"で指定する戻り値の型もなんらかわりません。
例えば「引数を2倍にして返す」関数オブジェクトをラムダ式で作るときにはこのようになります。
#include <iostream> using namespace std; void main(){ int num=10; //ラムダ式 auto nibai=[](int a)->int{ return a*2; }; //使い方 int result = nibai(num); //結果:result=20 }
通常の関数オブジェクトの記述より大幅に省略して同じ結果が得ることができます。ラムダの使い所はこのような単純な関数を複数作成しておくときや、イベントリスナーでよくあるコールバック関数の引数に直接記述できるところにあります。
続きですが最初にあった"[]"キャプチャの"="と"&"はどのようなものなのか説明します。まず"="はコピーキャプチャといい関数処理の中
外部の変数をラムダ式定義時にコピーして扱うことができます、"&"は参照キャプチャといい関数処理内
外部の変数を参照して扱うことができます。つまりこういうことです。
#include <iostream> using namespace std; void main(){ int num=10; //コピーキャプチャ auto copy=[=]()->int{ return num*2; }; //参照キャプチャ auto ref=[&]()->int{ return num*2; }; num=15; cout<<copy()<<endl; //20 cout<<ref()<<endl; //30 }
コピーキャプチャではラムダ式宣言時の外部変数の中身を記憶しています、そのためその後変数の値がどうなろうが知ったこっちゃないということです。逆に参照キャプチャでは関数呼び出し時に外部変数を参照するので使用時までに変数の内容が変更された場合でも対応することができます。
最後に注意点としてはプログラム実行中でしか戻り値の型が決定しない場合などはラムダ式は使えないということです。つまり、処理内で条件分岐で違う型を返そうとしたりするのはもってのほかですが再帰で複雑なことをしたりするときは注意が必要です。