いいえ、通常の関数と同じではありません。通常の関数を使用すると、宣言できます
void foo(int);
void foo(double);
ヘッダーで、 などのソース ファイルで関数を定義し、 などのfoo.cc
関数を使用する必要があるソース ファイルにヘッダーを #includebar.cc
し、残りはリンカーに任せます。コンパイラは、関数がどこかに定義されていることを確信して をコンパイルbar.cc
して生成bar.o
します。定義していない場合は、リンク時エラーが発生します。
ただし、テンプレートを使用している場合:
template <typename T>
void foo(T) ...
それがどのように機能するか想像してみてください。ソース ファイルfoo.cc
とソース ファイルbar.cc
は独立しており、お互いについて何も知りませんが、両方が #include するヘッダーの内容に同意することを除きます (これが全体的な考え方です)。そのため、実装bar.cc
方法がわからず、これらの関数で何ができるかわかりません。このシナリオでは、 はT に指定する型を知りません。では、太陽の下ですべての型名の定義をどのように持つことができるのでしょうか?foo.cc
foo.cc
bar.cc
foo.cc
bar.cc
foo.cc
できないため、このアプローチは許可されません。ヘッダーにテンプレート全体を含める必要があります。これにより、コンパイラはfoo(int)
、 またはfoo(string)
、 またはfoo(myWeirdClass)
、または必要なものの定義をbar.cc
作成し、それをビルドできますbar.o
(または、テンプレートがその型に対して意味をなさない場合は文句を言います)。
クラスについても同様です。
テンプレートの特殊化ではルールが少し異なりますが、高度なテクニックを試す前に、基本をよく理解する必要があります。