2013-07-10 107 views
4

這是一個出於對C++規則的好奇而沒有任何實際用法的問題。當模板玩弄的時候,我創建了一個類層次結構如下所示:不同專業化的模板類繼承

#include <stdio.h> 

// Declaration 
template <int X = 0> 
struct A; 

// Specialization for X = 0 
template <> 
struct A<0> 
{ 
    virtual void foo() 
    { 
     printf("A<0>::foo()\n"); 
    } 
}; 

// Extended generalized implementation 
template <int X> 
struct A : public A<0> 
{ 
    virtual void foo() 
    { 
     printf("A<1>::foo()\n"); 
    } 

    virtual void bar() 
    { 
     printf("A<1>::bar()\n"); 
    } 
}; 

int main() 
{ 
    A<> a0; 
    A<1> a1; 

    a0.foo(); 
    a1.foo(); 
    a1.bar(); 

    return 0; 
} 

此代碼編譯在Visual Studio的罰款,併產生預期的輸出:

A<0>::foo() 
A<1>::foo() 
A<1>::bar() 

這是一個有效的C++設計實踐?對我來說,這看起來很奇怪,所以我想知道這是否是某種未定義的行爲,這種行爲恰好發生在取決於具有許多陷阱和陷阱的編譯器的情況下,或者它是模板的明確用法。

看到這個的任何實際例子會很有趣。

+4

沒有未定義的行爲。它按預期工作。模板實例化可以從另一個模板實例化派生(請記住,同一模板的兩個獨立實例是兩個獨立的類)。例如,當且僅當'X!= 0'時,這允許你有一個'A ',它有一個函數'bar()'。 –

回答

3

這是遞歸定義template時常用的標準技術。

這樣的技術的一個例子是整數的序列:

template<int...s> struct seq {typedef seq<s...> type;}; 

特別是,在其生成:

template<int max, int... s> struct make_seq:make_seq<max-1, max-1, s...> {}; 
template<int... s> struct make_seq<0, s...>:seq<s...> {}; 

其通過從不同的實例化的繼承遞歸和簡單地描述template

要明確,make_seq<7>::typeseq<0,1,2,3,4,5,6>通過7級遞歸繼承。

0

就C++而言,這是有效的。班級模板A<1>與另一班級模板A<0>完全不同。

實際上,您在此創建的內容與所謂的Curiously Recurring Template Pattern類似。