web-dev-qa-db-ja.com

C ++テンプレートは単なる栄光のマクロなのでしょうか?

このようなC++テンプレートとC#/ Javaジェネリックのさまざまな比較から

https://stackoverflow.com/questions/31693/what-are-the-differences-between-generics-in-c-and-Java-and-templates-in-c/31929#31929

C++テンプレートは、コンパイルではなく、なんらかの前処理(解析前のプレーンテキストの置換)によって実装されるという認識を得ました。 C++テンプレートでの型チェックはCマクロに似ているためです。つまり、いくつかのエラーがある場合、それらはテンプレート自体からではなく、テンプレート化されたコードブロックを処理した後に生成されたコードからのエラーです。つまり、Cのマクロの上位バージョンの1つにすぎません。

次に、これをサポートする他のいくつかの事実を見つけました

  • C++テンプレートが前処理によって実装されている場合、動的リンク(.dllを使用)で問題が発生すると考えました。そして、すばやくグーグルでこれをサポートしました。

  • もう1つのポイントは、整数定数をテンプレートの引数として渡すことができるということです。そしてそれはある種の再帰もサポートします。しかし、この再帰はコンパイルされたアセンブリ/マシンコードにはありません。再帰呼び出しは、再帰呼び出しごとに関数を生成することにより、コンパイル時に管理され、より大きくてもより高速な実行可能バイナリを持ちます。

Cマクロとは異なり、いくつかの優れた機能があります。しかし、C++テンプレートはなんらかの前処理を使用して実装されていませんか?これは異なるC++コンパイラでどのように実装されますか?

27
Gulshan

C++テンプレートは、LISP(または、さらには、Scheme)マクロの一種です。これはコンパイル時に評価されるチューリング完全言語ですが、その言語から基礎となるC++環境へのアクセスがないため、厳しく制限されています。したがって、はい、C++テンプレートは、生成されるコードとの相互作用が非常に制限された、何らかの前処理と見なすことができます。

10
SK-logic

おそらく最大の違いは、Cマクロが他のコンパイルが行われる前の前処理フェーズで展開されるのに対し、C++テンプレートはコンパイルの一部であることです。これは、C++テンプレートはタイプを認識してスコープが設定されていることを意味し、単純なテキスト置換ではありません。実際の関数にコンパイルできるため、マクロが持つほとんどの問題を回避できます。型認識であることは、それらが一般的または特殊化できることを意味します。たとえば、swapテンプレート関数を簡単に提供でき、オブジェクトがヒープメモリを管理する場合でも適切に機能する特殊化を簡単に記述できます。

したがって、C++テンプレートはマクロと同じ意味で前処理されていません。これらは一種のCマクロではなく、Cマクロを使用してテンプレートの機能を複製することは不可能です。

テンプレートは、リンクされたライブラリではなくヘッダーファイルにありますが、.dllを提供している場合は、使用するヘッダーファイルも提供していると考えられます。

41
David Thornley

それらの実装方法は重要ですか?初期のC++コンパイラは、コードをcコンパイラに提供するプリプロセッサにすぎませんでした。これは、C++が美化されたマクロにすぎないという意味ではありません。

テンプレートは、複数の型のコードを実装するための、より安全で効率的で特殊化できる方法(実際のWordではないと思います)を提供することで、マクロの必要性を排除します。

Cで型コードをテンプレート化するにはさまざまな方法がありますが、単純な型を超えてしまうと、どれも非常に良い方法とは言えません。

5
Martin Beckett

いくつかの違いがあります。たとえば、テンプレートを使用して、必要に応じて関数のオーバーロードをインスタンス化できますが、マクロを使用する場合は、コンパイラーから見えるようにするために、可能性のあるオーバーロードごとにマクロを1回展開する必要があるため、多くのことになります。未使用のコードの。

別の違いは、テンプレートが名前空間を尊重することです。

5
Simon Richter

私見、C++テンプレート、Cマクロは、2つのまったく異なる問題を解決するためのものでした。元のC++標準テンプレートライブラリは、コンテナークラス(配列、リンクリストなど)を、それらに一般的に適用される汎用関数(並べ替えや連結など)から完全に切り離すためのメカニズムでした。効率的なアルゴリズムとデータ構造の抽象的な表現があると、コードの表現力が高まります。これは、特定のデータで機能する関数を実装する最良の方法を推測する作業が大幅に減ったためです。 Cマクロは、インライン化されたコードで言語を「拡張」する手段を提供するという点で、LISPマクロで通常見られるものとはるかに一致していました。すばらしいのは、C++標準ライブラリがテンプレートの機能を拡張して、Cで#defineを使用する際の大部分をカバーしていることです。

2
Marc