关于c ++:为什么奇怪的重复模板模式(CRTP)有效

why curiously recurring template pattern (CRTP) works

我遇到了很多解释什么是CRTP,但没有解释为什么它起作用。

The Microsoft Implementation of CRTP in ATL was independently discovered, also in 1995 by Jan Falkin who accidentally derived a base class from a derived class. Christian Beaumont, first saw Jan's code and initially thought it couldn't possibly compile in the Microsoft compiler available at the time. Following this revelation that it did indeed did work, Christian based the entire ATL and WTL design on this mistake.

例如,

1
2
3
4
5
6
7
8
9
10
 template< typename T >
 class Base
 {
    ...
 };

 class Derived : public Base< Derived >
 {
    ...
 };

我理解为什么以及何时可以使用它。但我想知道编译器是如何以这种方式工作的。因为在我看来,由于无休止的递归,它不应该工作:类派生继承自base,其中derived是从base继承的类,其中derived是从base继承的类,其中derived…等等。请您从编译器的角度逐步解释一下它是如何工作的,好吗?


递归定义的类型并不少见:链表也是递归的。它之所以有效,是因为在循环的某一点上,您不需要完整的类型,只需要知道它的名称。

1
2
3
4
struct LinkedNode {
    int data;
    LinkedNode *next; // Look ma, no problem
};

就CRTP而言,这一点如下:

1
Base<Derived>

Derived实例化Base并不要求Derived是完整的,只需要知道它是一个类类型。也就是说,以下工作很好:

1
2
3
4
5
6
template <class>
struct Foo { };

struct Undefined;

Foo<Undefined> myFoo;

因此,只要Base的定义不要求Derived完整,一切都会正常工作。


1
public Base< Derived >

这里,Derived只指Base内用于T的一个字体名,仅此而已。当然可以得到无限递归,但这完全取决于如何在Base中使用TT本身只是一个类型,就像其他类类型一样,类型本身并没有做任何事情。