持っているテンプレートクラスの呼び出しに問題があります。テンプレートである新しい型名Arrayを宣言しました。
.hppファイル内:
template <typename T>
class Array
{
public:
Array();
};
.cppファイル:
template <typename T>
Array<T>::Array()
{
//Do something
}
主に:
Array<int> arr;
リンケージエラーが発生します:ctorへの未解決の外部シンボル。
何か案が?
メンバー関数を含むテンプレート関数は、すべてヘッダーファイルに記述する必要があります。つまり、テンプレートクラスがある場合、その実装は完全にヘッダーファイルになければなりません。これは、テンプレートのインスタンス化ごとにコードを生成するために、コンパイラーが(署名だけでなく)テンプレート定義全体にアクセスできる必要があるためです。
テンプレート宣言とテンプレート関数定義の両方をヘッダーファイルに入れます。ほとんどのC++コンパイラは、テンプレート用の個別のコンパイルモデルを簡単にサポートしていません。
テンプレート化された関数の定義が使用されている場所に表示されない場合(つまり、ヘッダーまたは同じCPPファイルにない場合)、 作成するインスタンス化をコンパイラーに指示する にする必要があります。
ここでの問題は、.cppファイルでコンストラクターの定義を非表示にしていることです。この定義はallタイプT
に適用されます。これには、使用するT
としてint
が含まれますが、宣言のみであるため、実際には定義は提供されません。
リンカはシンボルArray<int>::Array()
を見つけることができません。
これで、次のような行を追加できます。
Array<int> arr1;
array.cppファイルの最後に配置すると、コンパイラはinstantiateリンカーが探している正しい定義になります。ただし、これはone定義、Array<int>
の定義のみを提供し、その他は提供しません。
このソリューションは、別のテンプレートパラメータのArray
、たとえばdouble
が必要になるまで機能します。その時点で、次のものを追加する必要があります。
Array<double> arr2;
あなたのArray.cppファイルの終わりまで-これで、これが持続不可能であることがわかります!
C++で将来必要なany型を処理する必要がある場合は、今度はctor(およびおそらく他のすべてのメンバー関数)の定義をヘッダー(および何も残っていないので、.cppファイルを削除します。
上記のように、C++のテンプレートでは、新しいメソッドのプロセスがコンパイル時にコンパイラーによって実行されます。問題は、その間にthmのすべての定義を知る必要があるため、すべてのクラス/関数宣言がar hまたはhppである必要がありますファイル。
別の答えは、(メインではなく).cppファイルのみをコンパイルし、オブジェクトファイルのサイズを確認してからempty.cppファイルを作成してから、そのempty.cppをコンパイルします。最後に、両方のオブジェクトファイルのサイズを比較します。それらのサイズが同じであることがわかります。つまり、.cppファイルはコンパイラーにとって何の役にも立たないため、リンカーは何も見つけることができません。