0

Code::Blocks を使用してプロジェクトをビルドしています。このプロジェクトには 、 、 の 3 つのファイルが含まれてmain.cppTimeSeries.cppますTimeSeries.h。次のようにクラスTimeSeries.hの宣言を提供します。TimeSeries

template<class XType, class YType> class TimeSeries {
public:
    TimeSeries(void);
    ~TimeSeries(void);
};

その後、TimeSeries.cpp以下が含まれます: #include "TimeSeries.h"

template<class XType, class YType>
TimeSeries<XType, YType>::TimeSeries(void) {
}

template<class XType, class YType>
TimeSeries<XType, YType>::~TimeSeries(void) {
}

そして最後に、main.cpp含まれています

#include "TimeSeries.h"
typedef TimeSeries<float, float> FTimeSeries;

int main(int argc, char** argv) {
    FTimeSeries input_data;
    return 0;
}

C::B でビルドすると、次のエラーが発生します。

undefined reference to `TimeSeries<float, float>::TimeSeries()'

私に何ができる?

ありがとう、
CFP。

4

3 に答える 3

3

基本的に、すべてのテンプレート化されたコードはヘッダーで定義する必要があります。そうしないと、コンパイルされたユニットで何も使用されないため、ビルドされません。

各 cpp ファイルは個別のユニットとしてコンパイルされるため、コンストラクターとデストラクターはコンパイルされません。コンパイラは、TimeSeries.cpp をコンパイルするときに、main.cpp で使用するテンプレート引数の型を知る方法がありません。

于 2010-09-19T07:42:52.103 に答える
2

コードをヘッダー ファイルとソース ファイルに分割する理由は、宣言と実装を分離するためです。コンパイラは、ソース ファイル (コンパイル ユニット) をオブジェクト ファイルに変換できます。クラスと関数を使用する他のコンパイル ユニットは、ヘッダー ファイルをインクルードし、オブジェクト ファイルをリンクします。この方法では、コードを一度コンパイルするだけでよく、リンクすることで再利用できます。

テンプレートの問題は、テンプレートにパラメーターが指定されていない限り、コンパイラーがテンプレートをコンパイルできないことです。異なるパラメーターでインスタンス化された同じテンプレートは、異なる型になります。std::vector<int>そしてstd::vector<float>、コンパイラの観点からは、まったく関係がありません。このため、テンプレート クラスは通常、ヘッダー ファイルに完全に存在する必要があります。これは、テンプレートが使用される場合、コンパイラはパラメーターに応じてクラスを生成するために完全な定義を必要とするためです。

@Gabriel Schreiber が彼の回答で指摘したように、特定のパラメーター セットを使用してテンプレートをコンパイルし、リンクするだけで他のコンパイル ユニットで使用できるようにする必要があることをコンパイラーに伝えることができます。ただし、これによってテンプレートが他のパラメーター セットで使用可能になるわけではありません。

于 2010-09-19T11:14:09.303 に答える
1

これを .cpp ファイル (定義の下) に追加する必要があります。

template class TimeSeries<float, float>;

コンパイラが TimeSeries.cpp をコンパイルするとき、別のソース ファイルで使用されているため、テンプレートがどの型に必要かはわかりません。コンパイラに明示的に伝える必要があります。

Stroustrup のコピーまたはインターネットで、明示的なテンプレートのインスタンス化について読んでください。

于 2010-09-19T11:04:11.557 に答える