2011-12-01 54 views
7

在閱讀文章時,我遇到的語法如下:一個類怎麼能從一個基於它自己的模板繼承?

template <typename T> 
class MyTemplate 
{ 
    T* member; 
    T* method(); 
    // ... 
} 

class MyClass : public MyTemplate<MyClass> 
{ 
    // ... 
} 

我完全不明白怎麼MyClass可以從是基於自身的模板繼承。你能解釋一下這是如何工作的嗎?

回答

8

這就是所謂的Curiously Recurring Template Pattern,簡稱CRTP。它被用來通過利用這樣的事實來達到靜態多態性的效果,當你在class MyClass : public MyTemplate<MyClass>行中得到MyTemplate<MyClass>時,MyClass是半定義的(這是一個不完整的類型),所以你可以存儲指向該類型的指針,並且對它做些事情,不需要完整的類型。

+0

我不會說'MyClass'不完整。可能會出現這種情況,您希望爲該課程提供一些通用功能。例如[Example](http://drdobbs.com/cpp/184403484)。 –

+1

@ R.K在'public MyTemplate '點上,'MyClass'確實是一個不完整的類型。這意味着你可以存儲指針和引用等。 –

+0

是的,你是對的。現在我再次閱讀您的描述,這是正確的。例如,我認爲你的意思是MyClass是一個不完整的類型。 –

2

請問你能解釋一下它是如何工作的嗎?

呃......它只是..呢?該標準特別允許模板參數爲不完整類型。由於CRTP基類中沒有方法需要完全定義的類型,所以一切都很好。

§3.9.2P3 [basic.compound]允許
指向不完全類型雖然有什麼可以跟他們(3.11)來進行限制。

§14.3.1p2 [temp.arg.type]
[注意:模板類型參數可能是不完整類型(3.9)。 - 注意]

2

這就是所謂的CRTP。它用於靜態多態性,可以比使用虛擬更快。

: public MyTemplate<MyClass> 

實例化MyTemplate<MyClass>,雖然自MyClass的是不完整的,你只能在不需要完整的類型方式使用T。如使用指針或調用成員函數。

總之,只要看看你的代碼片段,它本質上是一樣的:

class MyClass 
{ 
    MyClass* member; 
    MyClass* method(); 
} 

這是完全合法的和可以理解的。