5

私は特にラムダに興味のあるc++11を研究しています。

いくつかの練習の後、ラムダクロージャは無名関数オブジェクトであると思いました。

だから私はこのコードを書きました。

template <class callable_object>
void lambda_caller( callable_object lambda )
{
    std::cout<< sizeof(lambda) << endl;
    lambda();
}

テンプレートを使用する代わりに使用できることは知っていstd::functionますが、型キャスト中のオーバーヘッドは必要ありません。

しかし、この質問を読んで問題が1つ見つかりました。C++ 11でラムダのベクトルを作成できないのはなぜですか?

回答者は、「同じ署名を持っていても、すべてのラムダは異なるタイプを持っています。」と述べました。

コンパイラは、クラスごとに異なるコードを作成します。

lambda_callerしたがって、ラムダの別の定義を渡すたびに、コンパイラは別のバージョンのを作成すると思います。

使用する以外に、それを回避する方法はありますstd::functionか?ラムダクロージャのジェネリック型はありませんか?

4

2 に答える 2

5

あなたはそれを避けることはできません。Lambdaは、コードを実行するoperator()()がオーバーロードされたクラスです。つまり、異なるコード-異なるクラスです。

于 2013-02-21T10:01:57.813 に答える
0

std::functionラムダクロージャのジェネリック型です。問題は、各ラムダが異なる変数をキャプチャする可能性があることです。したがって、ラムダが3つの変数をキャプチャしたか、4std::functionをキャプチャした可能性があるため、関数ポインタと一部のデータを言うことを減らすことはできません。データに十分なメモリが割り当てられていることを確認しますが、コスト(データはヒープに割り当てられる可能性があります)。

ただし、複数のラムダを格納する必要があり、コンパイル時にいくつあるかがわかっている場合。代わりにそれらを保存することができますstd::tuple。これにより、ラムダごとに異なるタイプが可能になります。残念ながら、C ++はまだタプルを反復処理する方法を提供していませんが、Boost.Fusionを使用することはできます。

于 2013-02-21T22:54:07.720 に答える