2011-09-12 73 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>'的符号被导出到目标文件中,而不是其他符号,尽管实际上编译器正确地执行了递归。 –