2017-06-29 9 views
1

エクスポートテンプレートは、テンプレートの実装が別のソースファイルに引き渡される2011年以前のC++の機能です。エクスポートテンプレートはどのように実装されますか?

According to this articleの場合、実装ファイルで使用されているタイプごとに手動で指定して「マニュアル」エクスポートテンプレートを作成することができます。これは特定のシンボルを作成するだけなので、オーバーロードされた関数と同様の方法であると考えられます。これがどのように実装されるのかは理解できます。

エクスポートされたテンプレート(exportキーワードによる)は任意です。任意のタイプのデータを渡すことができます。

この単純な例取る:Tはintfloat、又は特にstd::string(及び+演算子をオーバーロード任意の他のタイプ)であった場合、この例の組立出力が乱暴に異なるであろう

template<typename T> 
T add(T value1, T value2) { 
    return value1 + value2; 
} 

を。

これは完全に恣意的なので、コンパイラはどのようにこのキーワードを実装しますか?

私の推測はリンク時のコード生成であり、コードの表現を含むカスタムオブジェクトファイル形式を必要とする可能性が高いです。しかし、これはリンカをコンパイラにもして、プリプロセッサ - コンパイラ - リンカの分離を破ります。

答えて

0

テンプレート化されたものは、コンパイルされるコードによって参照されるときにのみ具体的な型にインスタンス化されます。

この時点で、コンパイラはコードを生成するためにすべての情報(構造体定義、関数定義)を必要とします。

構造をインポートする際、コンパイラは見ているだけ定義が

export templat<...> class foo; 

である場合には、コードを生成するための機構がないと、クラスfooの機能が要求されたときに失敗しました。

逆に、ライブラリをビルドしているときは、コンパイラは定義と実装をすべて利用できますが、ライブラリで使用できるタイプは認識できません。

利用可能な(必要な)メカニズムは、ヘッダーファイルのみです。これには定義と実装があり、特殊なオブジェクト形式が不要です。

テンプレートの具体的な例を明示的にインスタンス化すると、ライブラリからエクスポートすることができますが、事前に知られているタイプのみをエクスポートすることができます。

1

2001年頃にEDGはexportを実装し、Comeauは私に初期のビルドを提供しました。私は実際にA<B<A<B<A<int> > > > >をインスタンス化することができました。A<T>がA.cppで定義され、B<T>がB.cppで定義されました。明らかに、これにはある種のリンクタイムコード生成が必要です。

Comeauがバックエンドとして実際にMSVCを使用したため、これはさらに驚異的でしたが、同時にMicrosoftはこれが不可能だと主張していました。 (これが私が最初にexport、WG21論文N1426を評価していた理由です)

関連する問題