私はメタプログラミングが一般的であり、特にC ++で何であるかを理解しようとしています
メタプログラミングで理解できることはまだ一般的に言っていないため、答えに共通の出発点はありません。
ウィキペディアの定義はこれで十分だと思います。
メタプログラミングとは、コンピュータプログラムが他のプログラムをデータとして扱う機能を持つプログラミング手法です。
...計算を実行時からコンパイル時に移動し、コンパイル時の計算を使用してコードを生成するために使用できます...
C ++では通常、自己変更コードを許可していないため、無視します。また、コンパイル時(またはほぼ間違いなく直前)のテキスト置換はプログラムのセマンティクスの操作と同じではないため、プリプロセッサーをカウントしないことも選択しています。
私の質問は、C ++でのテンプレートのすべての使用がメタプログラミングとして分類されるかどうかです
いいえそうではありません。
参考までに、
#define MAX(a,b) ((a) > (b) ? (a) : (b))
これは、max
テンプレートを使用せずに一般的な(型にとらわれない)関数を書く方法です。プリプロセッサをメタプログラミングとして数えないことはすでに述べましたが、いずれにしても、使用されるたびに常に同じコードを生成します。
後の変換フェーズで、そのコードの解析、型、およびa>b
コンパイラに定義されているかどうかの心配を委任するだけです。コンパイル時に動作するものはありません...に応じて異なる結果コードを生成します。コンパイル時には何も計算されません。
これで、テンプレートのバージョンを比較できます。
template <typename T>
T max(T a, T b) { return a > b ? a : b; }
これは単にテキストによる置換を実行するだけではありません。インスタンス化のプロセスはより複雑で、名前のルックアップルールとオーバーロードが考慮される場合があります。また、ある意味では、異なるインスタンス化はテキスト的に同等ではない場合があります(例:使用するものbool ::operator< (T,T)
と使用するbool T::operator<(T const&)
もの)。
ただし、各インスタンス化の意味は同じで(operator<
異なるタイプの互換性のある定義を想定している場合など)、タイプや名前などを解決するコンパイラーの通常の(機械的な)プロセスを除いて、コンパイル時に何も計算されませんでした。
余談として、それはあなたのプログラムが含まれていることを十分に間違いはありません何をすべきか、それを伝えるために、コンパイラのための命令をそれが何だから、すべてのプログラムがあります。
今、次のような限界的なケースがあります
template <unsigned N>
struct factorial() { enum { value = N * factorial<N-1>::value }; };
これは計算をコンパイル時間に移動します(この場合、ターミナルケースを書くのに煩わされないので、終了しない計算になります)が、おそらくメタプログラミングではありません。
ウィキペディアの定義では、計算をコンパイル時に移動することを述べていましたが、これは単なる値の計算にすぎません。コードの構造やセマンティクスについてコンパイル時に決定を下すものではありません。