理解するための基本的な考え方は、テンプレートのインスタンスがちょうどクラスであるということです。基本的に他のどのクラスとも変わりません。
あなたは典型的なテンプレート定義があります。そして、
template<typename T> class Base;
テンプレートのインスタンスを:
Base<int>
は、その名前のちょうどクラスです。 int
とは何の関係もなく、まったく関係がありません。まったくint
です。それは、それを何らかの形で、あるいは何らかの形で継承しません。
次のステップ:
class Derived;
template<typename T> class Base {};
Base<Derived> foo;
再び、Base<Derived>
だけクラスです。 Derived
と本質的な関係はありません。それから派生するものではなく、それを継承するものではありません。これはBase<Derived>
と呼ばれるクラスから継承Derived
と呼ばれるクラスを宣言し
template<class T>
class Base
{
};
class Derived : public Base<Derived>
{
};
:
だから、今、私たちは最後の一歩を踏み出します。
Base<Derived>
は単なるクラスです。とてもシンプルなクラスです。それより簡単なことはできません。方法はありません。メンバーはいません。私的でも、保護されていたり、公的でもない。それは小さなクラスですが、他のクラスと同じ権利と特権を持っています。あなたはそれへのポインタを宣言することができます。またはそれへの参照。それは単なるクラスです。
ここでも、重要な概念は、テンプレートのインスタンスが単なるクラスであることです。パラメータであるクラスからテンプレートへの「継承」はありません。この場合、テンプレートインスタンスは完全に空ですが、他のクラスが実行できるものはすべて実行できます。パブリック、プライベート、および保護されたメンバーを持つことができます。他のクラスから派生することもできます(テンプレートインスタンスは単なるクラスなので)。テンプレートインスタンスは単なるクラスであるため、他のクラスもテンプレートインスタンスから派生することができます。
ここに無限のネスティングはありません。別のクラスから継承しているクラスが1つだけあります。 2番目のクラスはテンプレートインスタンスになりますが、テンプレートインスタンスは単なるクラスであると言われましたか?
'Base'の文脈では、' T'は完全に完全な型ではありません。このため、 'Base'から' T'で定義された 'typedef'のようなものにはアクセスできません([1](http://stackoverflow.com/questions/6006614/c-static-polymorphism-crtp- (2)(http://stackoverflow.com/questions/652155/invalid-use-of-incomplete-type)を参照してください)。 'T'は完全に完全な型ではないので、コンパイラはこの状況で無限に再帰する必要はありません。少なくともそれは私の理解です。 – Cornstalks
@Eichhörnchen私は基底から継承したDerivedによってテンプレート化されたBaseから継承したDerivedによってテンプレート化されたBaseから派生しているので... –
@Cornstalksまあまあまあ聞こえます –