違いは正確には何ですか?用語は多少互換的に使用できるようですが、Objective-c のウィキペディアのエントリを読んでいると、次のように出くわしました。
C の手続き型プログラミングのスタイルに加えて、C++ は特定の形式のオブジェクト指向プログラミング、ジェネリック プログラミング、およびメタプログラミングを直接サポートします。
C++ を参照してください。どうやら彼らは違うのですか?
違いは正確には何ですか?用語は多少互換的に使用できるようですが、Objective-c のウィキペディアのエントリを読んでいると、次のように出くわしました。
C の手続き型プログラミングのスタイルに加えて、C++ は特定の形式のオブジェクト指向プログラミング、ジェネリック プログラミング、およびメタプログラミングを直接サポートします。
C++ を参照してください。どうやら彼らは違うのですか?
他のいくつかの回答ですでに述べたように、ジェネリックプログラミングと(静的/コンパイル時)メタプログラミングの両方がテンプレートで行われるため、C++では区別が混乱する可能性があります。さらに混乱させるのは、C++ のジェネリック プログラミングでは実際にメタプログラミングを使用して効率を高めていることです。つまり、テンプレートの特殊化により、ジェネリック プログラムから特殊化された (高速な) プログラムが生成されます。
また、すべての Lisp プログラマーが知っているように、コードとデータは同じものであり、「メタプログラミング」などは実際には存在しないことに注意してください。すべては単なるプログラミングです。繰り返しになりますが、これは C++ ではわかりにくいです。実際には、プログラミング (C ファミリーの命令型、手続き型、オブジェクト指向言語である C++) とメタプログラミング (テンプレート、純粋に機能的な "偶発的な" " 純粋なラムダ計算と Haskell の間のどこかにある言語であり、実際にはプログラミング言語になることを意図したものではなかったので、非常に醜い構文を使用します。)
他の多くの言語は、プログラミングとメタプログラミングの両方に同じ言語を使用しています (Lisp、Template Haskell、Converge、Smalltalk、Newspeak、Ruby、Ioke、Seph など)。
広い意味でのメタプログラミングとは、他のプログラムを生み出すプログラムを書くことを意味します。たとえば、C++ のテンプレートのようなものは、インスタンス化された場合にのみ実際のコードを生成します。テンプレートは、型を入力として受け取り、実際の関数/クラスを出力として生成するプログラムとして解釈できます。プリプロセッサは別の種類のメタプログラミングです。メタプログラミングの別の構成例: XML を読み取り、XML に従っていくつかの SQL スクリプトを生成するプログラム。繰り返しますが、一般に、メタプログラムは別のプログラムを生成するプログラムですが、ジェネリックプログラミングはパラメーター化された (通常は他の型を持つ) 型 (関数を含む) に関するものです。
この回答へのコメントを検討した後に編集
私は大まかにメタプログラミングを「プログラムを書くためのプログラムを書くこと」と定義し、ジェネリックプログラミングを「引数やメンバーのデータ型でパラメータ化された関数やクラスなどを書くために言語機能を使用すること」と定義します。
この標準により、C++ テンプレートはジェネリック プログラミング (など) とメタプログラミング (Boost や Spirit など) の両方に役立ちますvector
。さらに、C++ でのジェネリック プログラミング (つまり、コンパイル時のポリモーフィズム) は、メタプログラミング (つまり、テンプレート化されたコードからのコード生成) によって達成されると主張します。list
sort
ジェネリック プログラミングとは、通常、多くの型で機能する関数を指します。たとえば、1 つのソート関数で int の配列をソートし、別のソート関数で文字列のベクトルをソートする代わりに、同等のコレクションをソートできるソート関数。
メタプログラミングとは、クラス、モジュール、または関数をプログラムで検査、変更、または作成することを指します。
C++ では、1 つの機能でジェネリック プログラミングとメタプログラミングの両方がサポートされるため、他の言語を調べるのが最善です。(テンプレートは非常に強力です)。
Scheme / Lisp では、コードの文法を変更できます。人々はおそらく、Scheme を「括弧がたくさんあるプレフィックス言語」として知っていますが、非常に強力なメタプログラミング技術 (Hygenic Macros) も持っています。特に、try / catch を作成することができ、文法をある程度操作することもできます (たとえば、プレフィックス コードをもう記述したくない場合は、プレフィックスからインフィックスへのコンバーターを次に示します: http://github.com /marcomaggi/nausicaa )。これは、コードを作成するコードを作成するコードであるメタプログラミングによって実現されます。これは、プログラミングの新しいパラダイムを試すのに役立ちます (AMB 演算子は、非決定論的プログラミングで重要な役割を果たします。今後 5 年ほどで AMB が主流になることを願っています...)。
Java / C# では、ジェネリックを通じてジェネリック プログラミングを行うことができます。他の多くのクラスの型をサポートする 1 つのジェネリック クラスを作成できます。たとえば、Java では、Vector を使用して整数の Vector を作成できます。または、独自のクラスに固有のものが必要な場合は Vector 。
奇妙な点は、C++ テンプレートがジェネリック プログラミング用に設計されていることです。ただし、いくつかのトリックにより、C++ テンプレート自体はチューリング完全です。これらのトリックを使用して、メタプログラミングを通じて C++ 言語に新しい機能を追加することができます。複雑ですが、機能します。テンプレートを介して C++ に複数のディスパッチを追加する例を次に示します。http://www.eptacom.net/pubblicazioni/pub_eng/mdisp.html。より典型的な例は、コンパイル時のフィボナッチです: http://blog.emptycrate.com/node/271