6

ファンクターや関数ポインターに対するラムダ式の利点については、MSDNページでこの説明を読みました。「状態を保持する」能力とはどういう意味ですか?スコープを囲む際にrefまたはvalueによっていくつかの変数をキャプチャする機能に関連していますか?

http://msdn.microsoft.com/en-us/library/dd293608.aspx

コードを書くときは、おそらく関数ポインタと関数オブジェクトを使用して問題を解決し、計算を実行します。関数ポインターと関数オブジェクトの両方に長所と短所があります。関数ポインターは構文上のオーバーヘッドを最小限に抑えますが、スコープ内の状態を保持しません。関数オブジェクトは状態を維持できますが、クラス定義の構文上のオーバーヘッドが必要です。

ラムダ式は、関数ポインターと関数オブジェクトの利点を組み合わせ、それらの欠点を回避するプログラミング手法です。Lambda式は柔軟性があり、関数オブジェクトと同じように状態を維持できます。また、そのコンパクトな構文により、関数オブジェクトに必要なクラス定義が不要になります。ラムダ式を使用すると、同等の関数オブジェクトよりも煩雑でエラーが発生しにくいコードを記述できます。

次の例では、ラムダ式の使用と関数オブジェクトの使用を比較しています。最初の例では、ラムダ式を使用して、ベクトルオブジェクトの各要素が偶数か奇数かをコンソールに出力します。2番目の例では、関数オブジェクトを使用して同じタスクを実行します。

トピックのスコープ、状態、状態の維持、ラムダ式の利点に関するいくつかの関連するリファレンスを指摘できますか?

4

1 に答える 1

12

ファンクターとラムダはどちらも、通常の関数に対してこの機能を備えています。関数呼び出しの間のものを覚えておく能力です。通常の関数には静的変数がありますが、それらはグローバルに一意であるため、独自の状態を持つ個別の関数オブジェクトが必要な場合は適切ではありません。ファンクタークラスの例を次に示します。

class Counter
{
    int n;
public:
    Counter() :n(0) {}
    int operator()() { return n++; }    
};

このクラスを使用すると、関数として機能するインスタンスを作成できます。これを呼び出すたびに、n の以前の値が記憶されます。

Counter x;
cout << x() << '\n';
cout << x() << '\n';
cout << x() << '\n';

通常の関数ではできません。しかし、ラムダでそれを行うことができます:

int n = 0;
auto x = [=]() mutable { return n++; };
cout << x() << '\n';
cout << x() << '\n';
cout << x() << '\n';
于 2012-07-04T06:58:48.547 に答える