プログラミング言語に用意されている記法の1つで、無名関数を簡潔に表現するものです。
通常の関数には名前がありますが、ラムダ式を用いることで、名前のない関数(無名関数、匿名関数)を簡潔に定義できます。
通常の関数の定義では、関数名、仮引数、戻り値の型を、プログラミング言語が定めた構文に沿って記述する必要があり、1度しか使用しない関数では面倒な仕事になります。また、実際に呼び出しをおこなう箇所と、関数の定義を記述する箇所とが離れてしまうことで、コードの見通しが悪くなることもあります。
ラムダ式はこうした問題の解消に有効な機能です。必要となるその箇所に直接、関数を記述できるので、面倒が減り、呼び出し箇所と定義の箇所が離れてしまう問題も避けられます。
ラムダ式は、C++、Java、Python などのプログラミング言語で用いることができます。
C++ のラムダ式は次のような構文で記述します。
[](仮引数の並び) -> 戻り値の型 {本体}
C++ のラムダ式は、コンパイラによって関数オブジェクトの定義へと変換されます。そのため見方を変えると、関数オブジェクトを簡潔に記述する機能であるともいえます。上記の基本的なラムダ式の構文からは、以下の関数オブジェクトが生成されます。
class ???? {
public:
inline 戻り値の型 operator()(仮引数の並び) const
{
本体}
};
たとえば、[](int e) -> bool { return e < 0; };
というラムダ式からは、以下の関数オブジェクトが生成されることになります。
class ???? {
public:
inline bool operator()(int e) const
{
return e < 0;
}
};
ラムダ式の「戻り値の型」の部分は、「本体」のコードから型推論させることができるため、実際には [](int e) { return e < 0; };
のようにさらに簡潔に記述できます。
関数オブジェクトは関数のように呼び出すことができますから、[](int e){ return e < 0; }(-123);
のように呼び出すこともできますし、auto is_negative = [](int e){ return e < 0; };
のように受け取ったのち、is_negative(-123);
のように呼び出すこともできます。
ラムダ式の本体のコードから、ラムダ式の外側で定義されている変数にアクセスするために、キャプチャという機能があります。
int main()
{
std::vector<int> v {8, 11, -10, 0, -5, 13};
int min {};
std::cin >> min;
// 変数min 以上の値を持つ要素の個数を数える
std::cout << std::count_if(std::cbegin(v), std::cend(v), [min](int e){ return e >= min; }) << "\n";
}
このプログラムで使われているラムダ式で、[min]
の部分がキャプチャです。ここでは変数min をキャプチャしています。キャプチャされた変数は、生成される関数オブジェクトのデータメンバとなるため、本体のコード(operator()
の中)から使用できるようになります。
class ???? {
int min; // 値は、キャプチャされた変数からコピーされてくる
public:
inline bool operator()(int e) const
{
return e >= min;
}
};
この場合、対象の変数をコピーするコピーキャプチャですが、参照を用いる参照キャプチャもあります。
C++ のラムダ式についての詳細な解説は、新C++編「関数ポインタとラムダ式」にあります。
Programming Place Plus のトップページへ
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
![]() |
管理者情報 | プライバシーポリシー |