ラムダ式は、C++11以降で導入された機能であり、関数オブジェクトを簡潔に定義できる仕組みです。特にmain関数内でのローカル関数定義や、グローバル変数の乱用を避けたい場面で非常に有用です。
基本構文
auto lambda = [capture](parameters) -> return_type {
// 関数本体
};
ただし、戻り値型が明確な場合は-> return_typeを省略でき、コンパイラが自動推論します。
キャプチャ方式
ラムダ式は外側のスコープにある変数を「キャプチャ」して利用できます。主なキャプチャ方法は以下の通りです:
[=]:値によるキャプチャ(読み取り専用)[&]:参照によるキャプチャ(読み書き可能)[var, &other]:個別指定による混合キャプチャ
実用例:重複のない最長部分列の長さを求める
#include <bits/stdc++.h>
using namespace std;
void solve() {
const int n = 10;
int arr[] = {1, 2, 3, 4, 5, 6, 7, 7, 8, 9};
auto has_duplicate = [&](int left, int right) {
unordered_set<int> seen;
for (int i = left; i <= right; ++i) {
if (seen.count(arr[i])) return true;
seen.insert(arr[i]);
}
return false;
};
auto find_max_length = [&]() {
int max_len = 0;
for (int i = 0, j = 0; i < n; ++i) {
while (has_duplicate(j, i)) {
++j;
}
max_len = max(max_len, i - j + 1);
}
return max_len;
};
cout << find_max_length() << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
solve();
return 0;
}
再帰的なラムダの実現
ラムダ式は匿名であるため、自分自身を呼び出すにはstd::functionを使用して型を明示的に宣言する必要があります。
#include <functional>
#include <iostream>
using namespace std;
void recursive_example() {
function<void(int)> print_descending = [&](int x) {
if (x <= 0) return;
cout << x << '\n';
print_descending(x - 1);
cout << x << '\n';
};
print_descending(3);
}
注意点
値キャプチャ([=])では、キャプチャされたオブジェクトは暗黙的にconst扱いとなるため、非constメンバ関数を呼び出せません。例えば、mapのoperator[]は非constなので、値キャプチャされたmapでは使用できません。このような場合は、参照キャプチャ([&])または引数として渡すことを推奨します。