2011-01-10 3 views
8

私はコンストラクトの一般的な要点を得ていると確信していますが、私はそれらの目的をC++で見ることはできません。私はSOや他の場所でこのトピックの前の記事を読んだことがありますが、なぜそれらが新しい言語機能でなければならないのか分かりません。C++ 0x lambdasとoperator()、closureとfunctorの違い

私は答えたい事がthusly

  • ラムダと機能/ファンクタを受け入れるテンプレート引数の違いは何です。

  • クロージャは、一部のオブジェクト状態(スコープ?)を持つファンクタですか?

  • これらの構成の「キラーアプリ」とは何ですか?あるいは典型的なユースケースですか?
+0

ラムダを記述するために5.1.2の標準で5ページ以上が必要です。直接の質問がある場合、簡単な答えを出す唯一の方法です。 –

+2

PDC10のHerb Sutterの "Lambdas、Lambdas Everywhere"プレゼンテーションは、C++でラムダを説明するうえで非常に役立ちます。 http://herbsutter.com/2010/10/30/pdc-languages-panel-andshortened-lambdas-talk/またはhttp://bit.ly/dcJcXN –

+0

@Eugenリンクをありがとうございます。 Eugen –

答えて

17

ラムダは実際にはファンクタの構文砂糖です。新しいクラスの定義、取得された値と参照を保持するメンバ変数の作成、コンストラクタへのフックアップ、operator()()の作成、最後にインスタンスの作成と渡しなど、すべて自分で行うことができます。または、コードの1/10のラムダを使用して同じように動作させることもできます。

キャプチャしていないラムダは、関数ポインタに変換できます。すべてのラムダをstd::functionに変換するか、独自の固有の型を取得して、ファンクタを受け入れるテンプレート化されたアルゴリズムでうまく動作します。

+1

匿名のファンクタを使用できますか?ファンクタは戻り値の型を推定できますか?ファンクタは暗黙的にコンテキストを取得し、lambdasのようなルックアップを行うことができますか?式の代わりにファンクタを作成できますか? –

+0

これは私がファンクションアトムを教えている方法です。トピックが発生したときに説明するのは簡単なので、コードの量については本当に心配しません。また、それは古いスタイルで非常にエレガントなようです。 –

+0

ラムダを言語の一部にしたキラーアプリは何ですか?コードの1/10は私のセールスポイントではありません。 –

10

あなたは実際に用語に精通していない可能性があるため、実際にはさまざまな質問をしています。私はすべてに答えようとします。

ラムダと "operator()"の違いは何ですか? - これを言い直してみましょう。 "ラムダとオブジェクトの違いは何ですか?"

基本的には何もありません。主な違いは、ラムダ式が機能オブジェクトを作成し、operator()を持つオブジェクトが機能オブジェクトであることです。最終的な結果は、(params)構文で呼び出すことができるエンティティでも同様です。

クロージャとファンクションの違いは何ですか?これもやや混乱している。あなたが見ることができるように、クロージャは、それがその範囲内で、それが利用可能な変数を吸収するような範囲内で定義された「ファンクタ」の一種である、だから、

http://en.wikipedia.org/wiki/Closure_(computer_programming) http://en.wikipedia.org/wiki/Closure_(computer_programming)#C.2B.2B

:このリンクを確認してください。言い換えれば、プログラムの動作中にその場で構築される関数、およびそのビルドプロセスは、それを含むスコープのランタイム値によってパラメータ化されます。したがって、C++クロージャでは、ラムダを構築する関数内の値を使用するラムダがあります。

ファンクション/ファンクタを受け入れるラムダとテンプレート引数の違いは何ですか? - これは再び混乱します。違いは、彼らはまったく同じものではないということです。ファンクション/ファンクタを受け入れるテンプレートの「引数」はすでに混乱していますので、引数は何も受け付けないので、「ファンクション」を意味する「アーギュメント」とみなします。この場合、ラムダは引数としてファンクタを受け入れることができますが、ラムダはファクタ化することはできません。 2つ目は、ラムダは、ファンクション引数を受け入れる関数に引数として渡されるものです。

クロージャは、一部のオブジェクト状態(スコープ?)を持つファンクタですか?

上記のリンクからも分かるように、実際には、クロージャーは実際には状態を持っていません。閉鎖は、それを構築した他のエンティティの状態に基づいて構築されます。これは、状態ではありませんが、そのファンクタ内では、オブジェクトの構造です。

これらの構成の「キラーアプリ」とは何ですか?あるいは典型的なユースケースですか?

私は「なぜこれらのものは役に立ちますか」と言い直します。

一般的に、operator()を持っていれば、オブジェクトを関数として扱うことができます。 1つは、オブジェクトまたはフリー関数を使用してstdlibアルゴリズムの動作を拡張することができます。これが持っている有用性の膨大な供給を失うことは不可能です。

より具体的には、ラムダ式について言えば、このプロセスを簡単にするだけです。オブジェクト定義によって課せられた制限は、stdlibアルゴリズムを(プログラムの効率ではなく開発使用の観点から)若干非効率的にするプロセスを作りました。 1つは、少なくとも、テンプレートとしてパラメータとして渡されたオブジェクトは、すべて外部定義されていなければなりません。私はそれも変わってきていると信じていますが、ただ一つの場所でしか使えない基本的なものを実行するためにオブジェクト全体を作成する必要があり、不便です。ラムダ式は、その定義が使用されている場所などの範囲内で非常に簡単であることを可能にします。

+0

私は本当にあなたの答え+1が好きです。 「一般的には、演算子()があればオブジェクトを関数として扱う能力は非常に有用です」 - 私の元の質問に戻ってくれます。 –

+0

私はいくつかを見て、私はそれらのすべてにできる最高の答えを与えたので、あなたは元の質問を次に指摘する必要があると思います。 –

+0

それは3つの部分の質問だったし、私はそれをお詫び申し上げます。あなたの答えは私に良い洞察を与えました。私は本当にあなたの答えをありがとう –

関連する問題