为什么CRTP不会导致无限嵌套?

时间:2016-10-03 03:11:06

标签: c++ inheritance template-meta-programming crtp

我对如何编译CRTP感到困惑。如果我们有这样的事情:

template<class T>
class Base
{

};
class Derived : public Base<Derived>
{

};

为什么在编译期间没有类似的事情发生?

X[Y]表示X继承自Y)

声明Derived个实例 Derived d;

d正在扩展为模板和继承的无限复发

d[Base<Derived[Base<Derived[Base<Derived[Base<Derived[...]>]>]>]>]

为什么不发生这种情况?关于CRTP的所有教程只解释了你可以用它做什么,而不是在幕后发生的事情(至少含糊不清)。

2 个答案:

答案 0 :(得分:7)

要理解的基本概念是模板的实例只是一个类。它根本没有任何其他类别。

如果您有典型的模板定义:

template<typename T> class Base;

然后是模板实例:

Base<int>

只是该名称的一类。它与int无关,与int完全没有任何关系。它不会以某种方式或以任何方式从中继承。

下一步:

class Derived;

template<typename T> class Base {};

Base<Derived> foo;

同样,Base<Derived>只是一个类。它与Derived没有内在联系。它不是从它衍生出来的,也不是从它那里继承而已,没有。

所以,现在我们采取最后一步:

template<class T>
class Base
{

};

class Derived : public Base<Derived>
{

};

这声明了一个名为Derived的类,它继承自名为Base<Derived>的类。 Base<Derived>只是一个类。这是一个非常简单的课程。不能比这更简单。它没有任何方法。它没有任何成员。也不是私人的,受保护的或公共的。它是一个小班级,但它拥有与其他班级相同的权利和特权。您可以声明指向它的指针。或者引用它。它只是一堂课。

同样,关键概念是模板的实例只是一个类。它没有继承&#34;以任何方式从参数到模板的类。在这种情况下,模板实例是完全空的,但它可以执行任何其他类可以执行的任何操作。它可以拥有公共,私人和受保护的成员。它可以从一些其他类派生,它可以是另一个模板实例(因为模板实例只是一个类)。或者,其他一些类可以从模板实例派生,因为模板实例只是一个类。

这里没有无限的筑巢。你只有一个继承自另一个类的类。第二个类恰好是一个模板实例,但我碰巧提到模板实例只是一个类吗?

答案 1 :(得分:3)

简单说明:因为以下内容完全有效:

template<class T>
class Base
{
};

class Derived /* at this point, Derived is declared (not defined) */;

int main()
{
    Base<Derived> base;  // the definition of Derived (or lack thereof) is irrelevant.
}