2013-03-27 9 views
5

私は、仮想メソッドをテンプレートとして宣言できないことを理解します。これは、コンパイラが仮想テーブルに予約するエントリの量を知らないためです。しかし、これは言語の問題ではなく技術的な制限です。コンパイラは実際に必要なテンプレートのインスタンス数を知ることができ、適切なvtableサイズを割り当てるために "戻る"ことができます。テンプレート仮想関数は使用できません。一時的な技術的な制限のみですか?

今後の標準で予定されている技術的な解決策はありますか?

+0

コンパイラの制限を無視できる場合は、達成したいことの例を挙げてください。 –

+0

もっと洞察に富んだアプローチは、現在のC++で同様のメカニズムを動作させるためにどのようなフープを実行しなければならないか、そしてそのプロセスをどのように自動化できるかを尋ねることです。結局のところ、任意の最終的なデータ構造は既に言語の表現力の範囲内にある。唯一の問題は、 'template <…> virtual'がそこに行く方法ではないということです。 – Potatoswatter

+1

@Roee:特に環境を理解しようとするだけのことはありません。 –

答えて

4

コンパイラはテンプレートのインスタンス化をすべて知ることはできません。現在のコンパイルモデルでは、各翻訳単位は別々にコンパイルされ、後にリンクされます。 1つの翻訳単位でテンプレート・タイプをコンパイルするとき、そのタイプのインスタンス化を別の翻訳単位で知らないでしょう。

ライブラリを作成していて、その中にテンプレート機能が必要だとします。ライブラリをコンパイルしてクライアントに配布します。クライアントはテンプレート引数を好きなようにテンプレート関数をインスタンス化できますが、ライブラリはすでにコンパイルされています。それは "戻って"これを変更することはできません。

テンプレート関数をコンパイルすると、その関数のすべてのインスタンス化も利用できると仮定しています。それはしばしばそうではなく、現時点でのコンパイルとリンクのモデルの下では、そうであることは分かりません。

+0

これは本当に正しいですが、ダイナミックなvtableで解決できませんでしたか?私はこれが必要な混乱のレベルを理解しています。 –

+0

一方、完全なプログラムを作成すると、テンプレートインスタンス化のセットが修正されました。基本クラスが定義されているのではなく、その時点で原則的に仮想メタデータを生成することができます。したがって、言語によって現在定義されているコンパイル/リンクモデル(そして動的リンクをサポートしたい場合はさらに多くの変更点)に根本的な変更が必要な、克服できない障害ではありません。 –

+1

@StefanoBorini確かに、それは解決できるかもしれません。不可能はない! C++プログラムがコンパイルされてリンクされる方法にかなりの変更を加える必要があります。これも標準に反映する必要があります。 –

3

これは確かにです。既存のリンカーを使用する必要はありませんが、これを行うにはが可能です。つまり、リンカーはそのテンプレート関数のすべてのインスタンス化を調べ、適切なデータ構造を構築できます。しかし、C++の強みの1つは、特殊なリンカーを必要としないことです。これは、リンカーが石で書かれていて変更できないシステムに移植可能にします。そして、そうです、それは起こります。リンカーはすべてオブジェクトコードが一致し、すべてシステムでサポートされているプログラミング言語と互換性がなければならず、時には古くて厄介なことを意味します。変更は破損の実質的なリスクをもたらす。理論的にはこれを行うことは可能ですが、それは起こりません。

1

現在、C++標準委員会papersおよびcore language issuesに基づいて計画されているものはありません。 C++標準では、C++の実装要件が規定されていますが、技術実装そのものは定義されていません。したがって、テンプレートの仮想関数は、技術的な制限ではなく、標準によって定義された言語の制限です。それにもかかわらず、言語の制限は、実装の技術的な制限の結果として課されるのではなく、既存の実装の変更に伴うリスクの結果である可能性があります。