コンパイラーは、ラムダ式の評価に基づいて匿名関数 (名前のない関数) オブジェクトを作成します。
ラムダ式によって作成されるこの関数オブジェクトは、オブジェクトが作成されたブロックよりも長く持続することがあります。関数オブジェクトが使用される前に破棄されてしまう変数を使用していないかを確認する必要があります。
次の例では、ラムダ式によって作成された関数オブジェクトが、どのようにそのオブジェクトを作成した関数よりも長く持続するかを示しています。
struct Base {
virtual bool test(int x) = 0;
};
template<typename F>
struct Derived: Base {
F f;
bool test(int x) {return f(x);}
Derived(F f_) : f(f_) {}
};
template<typename F>
Base* MakeDerived( F f ) {
return new Derived<F>(f);
}
Base* Foo( int k ) {
return MakeDerived( [k](int x) {return x%k==3;} );
}
bool Bar() {
Base* b = Foo(3);
return b->test(6);
}
上の例で Bar は、ラムダ式によって生成された関数オブジェクトを Derived テンプレート・クラスのインスタンスにコピーする Foo を起動します。ラムダ式は、ローカル変数 k を参照します。コピーされた関数オブジェクトを使用する前に、k を破棄しても、k はコピーによってキャプチャーされているためコードは安全です。