2011-09-12 106 views
5

鑑於像是遞歸顯式模板實例嗎?

template<int dim> class Point { ... }; 

模板這個模板可以顯式實例像

template class Point<0>; 
template class Point<1>; 
template class Point<2>; 
template class Point<3>; 

而不是單獨像上述實例每個模板,我想與像

一個呼叫遞歸實例化它們
template class RecursiveInstantiate<Point, 3>; 

其中RecursiveInstantiate<T, i>將實例化T<i>T<i-1>,...,T<0>。是否有可能創建這樣一個類RecursiveInstantiate?如果這是不可能的,你知道一種方法來處理預處理器嗎?

事實上,我有興趣將這個概括爲具有多個模板參數的類,如Node<int i1,int i2,int i3>,用於{0,1,2,3}中的i1,i2,i3的所有組合。但我希望能夠自己解決這個第二部分。

任何意見,也是一個解釋爲什麼它是不可能的,我想達到的讚賞。


更新:感謝您的意見爲止。我現在可以更清楚地看到問題的真相。該行

template class Point<3>; 

實例化模板並將其符號導出到目標文件。形式

template class RecursiveInstantiate<Point, 3>; 

的一個實例可以實例化的類class Point<3>class Point<2>,......顯然,這只是發生在本地,但。模板不會導出到目標文件。也許我將不得不尋找使用預處理器的解決方案。

正如我現在所看到的,我在開始時並沒有精確地提出我的問題,我非常感謝你的回答和選定的答案。

注:我想在linux上用g ++/clang作爲編譯器。

回答

8

你可以做一個小實例化類:

template <unsigned int N> struct Instantiator 
{ 
    Point<N> p; 
    Instantiator<N-1> i; 
}; 

template <> struct Instantiator<0> 
{ 
    Point<0> p; 
}; 

然後只需添加一個明確實例:template struct Instantiator<81>;

您可以按字典擴展這個想法到任意數量的積分參數。


由於@Georg說,讓我們使它通用:

template <template <unsigned int> class T, unsigned int N> struct Instantiator 
{ 
    T<N> t; 
    Instantiator<T, N-1> i; 
}; 

template <template <unsigned int> class T> struct Instantiator<T, 0> 
{ 
    T<0> t; 
}; 

template struct Instantiator<Point, 82>; 
+0

使它成爲'template struct I {T p; I ; }; ...'。此外,使用元算法和元函數可避免硬編碼參數計數(請參閱Boost.MPL的操作)。 –

+0

@Georg:我喜歡你的風格! –

+0

這個解決方案看起來非常好,我非常喜歡你的通用解決方案。我仍然努力爭取這個工作。該方法很好地編譯,是的,但不知何故'Point <0>'的符號不會導出到目標文件中,這就是代碼'template class Point <0>;'將要執行的操作。我將不得不在明天進一步調查。 我在Linux上使用g ++/clang,但我不確定這是否特定於我的架構。 –

4

可以是這樣做的:

template<int dim> struct Point { 
    static const int val = dim; 
    Point<dim - 1> p; 
}; 

template<> struct Point<0> { ... }; 

這創造了一個模板參數模板專業化當它是0所以遞歸停在那裏,當你實例化一個這樣的:

Point<4> 

它實例化從Point<4>Point<0>。那麼你可以做

Point<4>::val 

訪問該特定的值。

+3

這需要在Point'的'定義修改,並具有控制,雖然。 –

+0

@Kerrek這個概念可以很容易地擴展到使用而不需要修改'Point'。 –

+0

這種方法對我無效。如果我實例化'模板類Point <4>;'只有'Point <4>'的符號被導出到目標文件中,而不是其他符號,儘管實際上編譯器正確地執行了遞歸。 –