論理的に発生するのは、コンパイラが関数呼び出し演算子をオーバーロードした (ローカル) クラスを生成し、レキシカル クロージャーがその (ローカル) クラスのデータ メンバーによって表されるため、ラムダ関数の型を知ることはできません。これは、次のようなラムダ関数で論理的に発生することです。
auto foo = [](int x, int y) { return x + y; };
コンパイラは論理的にこれを行います。
struct CompilerGeneratedName { void operator()(int x, int y) const { return x + y; } };
CompilerGeneratedName foo;
コンパイラは (ローカル) クラスを生成するため、名前を生成するため、型を明示的に記述することはできません。型は、テンプレート関数の引数の型推定または auto/decltype を使用して推定することしかできません。
また、C++0x クロージャーは静的に割り当てられるため、生の C++0x クロージャーを安全に返すことはできません。
これを実現する方法はいくつかありますが、最初の方法はより柔軟で、レキシカル スコープをキャプチャするラムダ関数をサポートしています。std::function を使用します。外側のスコープから何もキャプチャしないラムダ関数がある場合は、関数ポインターを使用できますが、この変換は何よりもレガシーコードを操作するためのものです。
したがって、基本的にあなたが望むのはこれです:
std::function< int (int) > foo(int x)
{
return [x](int y)->int{return x * y;};
}
私が論理的に言い続けた理由は、boost::lambda のようなものはもともと (C++03 ではテンプレート関数の引数でローカル クラスを使用することを許可していませんが) 機能する方法であり、ラムダ関数を追加するというアイデアがどこから生まれたかです。からですが、これは言語機能であるため、コンパイラベンダーは、参照によってすべての環境をキャプチャする場合など、さまざまなより効率的な方法で実装できます。見る。