3

まとめ
この質問は、単一のテンプレート クラスのインスタンス化を複数の異なる翻訳単位で個別にコンパイルすることに関するものです。

質問
非テンプレート クラスの場合、定義をいくつかの .cpp ファイルに入れ、それらを個別にコンパイルできます。例えば:

ファイルああ:

class A {
public:
  void func1();
  void func2();
  void func3() { /* defined in class declaration */}
}

ファイル A1.cpp:

void A::func1() { /* do smth */ }

ファイル A2.cpp:

void A::func2() { /* do smth else */ }

今、私はテンプレートクラスで似たようなことをしようとしました. 必要なインスタンスが正確にわかっているので、テンプレートを明示的にインスタンス化しています。メンバー関数にはかなり大きな数式が含まれているため、各インスタンス化を個別にコンパイルしています。これにより、最適化レベルが高いとコンパイラが大幅に遅くなる可能性があります。だから私は次のことを試しました:

ファイル TA.h:

template <typename T>
class TA {
public:
  void func1();
  void func2();
  void func3() { /* defined in class declaration */}
}

ファイル TA1.cpp:

template <typename T>
void TA<T>::func1() { /* do smth */ }
template class TA<sometype>;

ファイル TA2.cpp:

template <typename T>
void TA<T>::func2() { /* do smth else */ }
template class TA<sometype>;

Linux では clang と GCC で動作しますが、Mac での GCC では重複シンボル エラー中のリンク中に失敗します (この例では、TA1.cpp と TA2.cpp の両方でインスタンス化された func3 が原因です)。

次に、標準で次の文に出くわしました。

C++ 11.14.7、パラグラフ 5:
与えられたテンプレートと与えられた一連のテンプレート引数について、
-- 明示的なインスタンス化の定義は、プログラム内で多くても 1 回しか現れない
-- ...

明示的なインスタンス化を使用している場合でも、テンプレート クラスの個別のコンパイルができない (許可されていない) ということですか (暗黙的なインスタンス化では明らかに不可能です)。

PS私は答えを得たので気にしませんが、ここで答えられると思う人は誰でもhttps://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-ヘッダファイルが間違っています。

4

2 に答える 2

1

テンプレートを個別にコンパイルするのは難しいですが、許可されています。できないことは、2 つの翻訳単位で同じ関数を定義できないのと同じように、複数の翻訳単位で型を明示的にインスタンス化することです。

于 2014-02-03T18:23:09.660 に答える