テンプレート化されたメンバー関数も持つテンプレート化された C++ クラスがあります。このメンバー関数のテンプレート パラメーターは、特定の方法でクラスのテンプレート パラメーターに依存しています (以下のコードを参照してください)。テンプレート パラメーターの 2 つの異なる値に対して、このクラスをインスタンス化しています (特殊化していません)。この時点まですべてがコンパイルされます。ただし、テンプレート化されたメンバー関数を呼び出すと、最初にインスタンス化されたオブジェクトの呼び出しのみがコンパイルされ、2 番目のオブジェクトはコンパイルされません。テンプレート クラスの 2 番目のインスタンス化に対して、コンパイラがテンプレート化されたメンバー関数をインスタンス化していないように見えます。「g++ filename.cpp」を使用して以下のコードをコンパイルすると、次のエラーが発生します。
filename.cpp:63: エラー: 'Manager<(Base)1u>::init(Combination<(Base)1u, (Dependent2)0u>*)' の呼び出しに一致する関数がありません</p>
これが電話の回線ですb.init(&combination_2)
g++ --version => g++ (Ubuntu/Linaro 4.4.7-1ubuntu2) 4.4.7
uname -a => Linux 3.2.0-25-generic-pae #40-Ubuntu SMP i686 i686 i386 GNU/Linux
enum Base {
AA,
BB,
CC
};
enum Dependent1 {
PP,
QQ,
RR
};
enum Dependent2 {
XX,
YY,
ZZ
};
template<Base B>
struct DependentProperty {
};
template<>
struct DependentProperty<AA> {
typedef Dependent1 Dependent;
};
template<>
struct DependentProperty<BB> {
typedef Dependent2 Dependent;
};
template <Base B, typename DependentProperty<B>::Dependent D>
class Combination {
public:
void reset() {}
int o;
};
template <Base B>
class Manager {
public:
template <typename DependentProperty<B>::Dependent D,
template<Base,
typename DependentProperty<B>::Dependent> class T>
void init(T<B, D>* t);
};
template <Base B>
template <typename DependentProperty<B>::Dependent D,
template<Base,
typename DependentProperty<B>::Dependent> class T>
void Manager<B>::init(T<B, D>* t) {
t->reset();
}
int main(int argc, char** argv) {
Manager<AA> a;
Manager<BB> b;
Combination<AA, PP> combination_1;
Combination<BB, XX> combination_2;
a.init(&combination_1);
b.init(&combination_2);
return 0;
}
実際のプロジェクトのサンプル コードから Base、Dependent、または Combination に対応するクラスを変更することは現実的ではありません。私が本当に疑問に思っているのは、Manager::init() を定義するための私の構文が間違っているのか、それともこのコードを許可しない C++ または g++ の既知のプロパティ/機能/制約があるかどうかということです。