C++ のラムダ式
C++ のラムダ式は、関数オブジェクトを簡易的な記法を用いてその場で定義するための機能です。
コールバック関数や、ソート処理などの比較関数で使われたりします。
C++11から使用できます。
構文
ラムダ式の構文は以下のような構造になっています。
[キャプチャ句](引数リスト) mutable 例外仕様 -> 戻り値の型 {
ラムダ式の処理本体
}
様々な要素で構成されますが、使用しないものは省略可能です。
例えば何もキャプチャせず、引数も取らず、何もしない最も単純なラムダ式は以下のようになります。
[]{}
使い方
引数と戻り値を持つラムダ式
2つの数を受け取り、足し合わせた数を返すラムダ式です。戻り値の型は推論されるため、この例では書かなくても問題ないです。
// ラムダ式の定義
auto add = [](int a, int b) -> int {
return a + b;
};
// ラムダ式を実行する
int result = add(1, 2);
// 3
std::cout << result << std::endl;
外部のスコープから変数をキャプチャするラムダ式
C++のラムダ式は、デフォルトでは外部のスコープの変数にアクセスすることができませんが、キャプチャ句にアクセス可能な範囲を指定することでアクセスできるようになります。
キャプチャ句で変数をキャプチャする場合、&
で参照キャプチャ、=
でコピーキャプチャとなります。また、変数個別にキャプチャ指定するだけでなく、すべての変数をキャプチャすることも可能です。
参照する場合でもラムダ式内で外部の変数を直接書き換えることはできません。後述の mutable
の指定が必要になります。
以下、キャプチャ句の指定方法のまとめとサンプルコードです。
記法 | 説明 |
---|---|
[] |
キャプチャしません。 |
[&] |
すべての外部変数を参照でキャプチャします。 |
[=] |
すべての外部変数を値(コピー)でキャプチャします。 |
[&x] |
変数 x を参照でキャプチャします。 |
[x] |
変数 x を値(コピー)でキャプチャします。 |
[&, x] |
デフォルトで外部変数を参照でキャプチャし、変数 x を値(コピー)でキャプチャします。 |
[=, &x] |
デフォルトで外部変数を値(コピー)でキャプチャし、変数 x を参照でキャプチャします。 |
コピーでキャプチャする場合はラムダ式の定義時、参照でキャプチャする場合は実行時の値が使用されます。
// この変数をキャプチャします
int a = 1;
// 値(コピー)でキャプチャするラムダ式
auto f_copy = [a]() { return a; };
// 参照でキャプチャするラムダ式
auto f_ref = [&a]() { return a; };
// キャプチャする変数を書き換える
a = 100;
// copy: 1
// ref: 100
std::cout << "copy: " << f_copy() << std::endl;
std::cout << "ref: " << f_ref() << std::endl;
外部のスコープの変数を書き換えるラムダ式 mutable
mutable
をで変更可能であることを指定するとラムダ式内で外部の変数を更新することができます。指定しないと更新はできないです。
以下、外部変数の値をカウントアップするラムダ式の例です。
int n = 0;
auto f = [&n]() mutable { n++; };
f();
f();
f();
// count: 3
std::cout << "count: " << n << std::endl;
なお、[n]() mutable { n++; }
のように、コピーでキャプチャしていると書き換えはできません。
例外の指定
noexcept
例外の指定を使用して、ラムダ式が例外をスローしないことを示すことができます。
らしいです。
// throw_lambda_expression.cpp
// compile with: /W4 /EHsc
int main() // C4297 expected
{
[]() noexcept { throw 5; }();
}
コメントを書く