関数、ADT、およびクラスの C および C++ での非常に一般的なコーディング パターンは次のとおりです。
- (クラスの関数の) 宣言を含むヘッダー .h ファイル。
- 実際のコードを含む実装 .cpp ファイル。
これらは個別のオブジェクト (共有または非共有) にコンパイルされます。宣言されたエンティティ ('foo' と呼びましょう) を使用する他のコードには、foo.h ファイルが含まれ、個別にコンパイルされてから foo.o に対してリンクされます。
ただし、テンプレート化された foo では、これは不可能です。必須のインスタンス化の型を指定しないと、foo.o は役に立ちません。誰もが行っているように見えるのは、実装コード (通常は foo.cpp) をユーザー コードと同じ翻訳単位に含めることです。
foo.cpp を含める必要のないメカニズムを使用して、これを回避できるようにしたいと思います。理想的には、これはうまくいくはずです:
main.cpp:
#include "foo.h"
int main() {
foo<int>();
}
foo.h:
template<typename T> void foo();
foo.cpp:
template<typename T> void foo() {
// implementation here
}
そのためには、実装コードを含める必要がなく、ヘッダーだけを含める必要があるように、ソース ファイルとヘッダー ファイルだけでなく、おそらくビルド メカニズムを含む、ある種の巧妙なイディオムが必要だと思います。おそらく、次のような行を持つ自動生成ヘッダーを含む、実装ファイルの行に沿って何かを考えていました
template foo<int>();
これは、オブジェクト ファイルが欠落しているインスタンス (つまり、2 つのコンパイル パス) の解析、またはソースの解析 (コンパイラの微調整? 補助出力の有効化?) です。そのようなイディオムを提案できますか?または、私が検討していない別の選択肢はありますか?
注:もちろん、要点は、foo モジュール ( foo.h
, foo.cpp
) のコードは、どのインスタンス化が必要かを「認識」していないということです。たとえば、またはmain()
を使用するかどうかを認識していません。foo<int>()
foo<unsigned char>()