2011-06-16 109 views
6

我有一个递归模板定义(我刚刚制定了这个术语)。我认为代码更好地解释它。递归模板定义

template<typename X> 
class Domain 
{ 
    public: 
     X begin; 
     X end; 

     Domain(
      X _begin, 
      X _end) 
      : begin(_begin) 
      , end(_end) 
     { 
      // ... 
     } 

     bool Contains(
      const X& t) const 
     { 
      // ... 
     } 
}; 

template<typename X, typename Y> 
class IFunction 
{ 
    public: 
     Domain<X> myDomain; 

    public: 
     IFunction(
      const Domain<X>& dom) 
      : myDomain(dom) 
     { 

     } 

     virtual Y 
     Calc(
      const X& IV) const = 0; 

     virtual IFunction<X, Y>* 
     GetDerivative() const = 0; 
}; 

template<typename X, typename Y, int n> 
class NthOrderFunction 
    : public IFunction<X, Y> 
{ 
    public: 
     double coeffs[n+1]; 

    public: 
     NthOrderFunction(
      const Domain<X>& dom, 
      ...) 
      : IFunction(dom) 
     { 

     } 

     virtual Y 
     Calc(
      const X& IV) const 
     { 
      // temporary compile solution 
      return Y(); 
     } 

     virtual IFunction<X, Y>* 
     GetDerivative() const 
     { 
      if (n > 1) 
      { 
       return new NthOrderFunction<X, Y, n-1>(dom, ...); 
      } 
      return new FlatLine<X, Y>(dom); 
     } 
}; 

我拿出了很多继承和其他关系来保持它的可读性,简单性和神秘性。因此,编辑代码时可能会出现新的错字,但请忽略它。该代码已运行良好多年,唯一的问题是我要指出的一个。

我最近添加了一个“GetDerivative”函数,它在NthOrderFunction类中的实现给我带来了问题。我知道模板类是在编译之前但在预处理之后定义的。因此,我看不到如何使这个功能有效。每个具有模板参数n的NthOrderFunction都需要带模板参数n-1的NthOrderFunction。你可以看到这是一个问题。问题是,尽管n永远不会被使用为负数,但是我不会做任何编码,将会说服“模板定义引擎”不会打扰n的实例。

有没有人有过这个问题?你有什么解决方案?

+0

这到底是什么B? – 2011-06-16 11:13:03

+0

对不起,一定是X,会编辑。 – Rene 2011-06-16 11:15:46

+1

你想使用模板元编程来处理多项式吗?我认为之前已经完成了:-) – 2011-06-16 11:22:02

回答

2

添加类似:

template<typename X, typename Y> 
class NthOrderFunction<X, Y, 1> 
    : public IFunction<X, Y> 
{ 
    public: 
     double coeffs[n+1]; 

    public: 
     NthOrderFunction(
      const Domain<X>& dom, 
      ...) 
      : IFunction(dom) 
     { 

     } 

     virtual Y 
     Calc(
      const X& IV) const 
     { 
      // temporary compile solution 
      return Y(); 
     } 

     virtual IFunction<X, Y>* 
     GetDerivative() const 
     { 
      return new FlatLine<X, Y>(dom); 
     } 
}; 

,并移除递归的情况下在n == 1例。

作为一个建议,得到一些书或教程或模板metaprogramming。其中一种基本技术是以这种方式在模板中使用递归。这严格来说不是元编程,它只是递归模板。本书/教程将解释如何使用更高级的技巧,在扩展时可以使用这些技巧。

这个原理的工作原理是,原始代码仍然会将编译时间“if”扩展到运行时代码(这将永远不会执行)。这段代码取代了可以编译出来的一种情况,因此没有无限递归的选择。

+0

thx!我读了它,这似乎合乎逻辑。我会试一试。 – Rene 2011-06-16 11:54:35

7

这与模板元编程101示例因子相同,只是内容稍微复杂一些。

template<int N> struct factorial { enum { value = N * factorial<N-1>::value }; }; 

而且您需要相同的解决方案 - 基础案例的专业化。

template<> struct factorial<1> { enum { value = 1 }; }; 

您的将是部分而不是完整的,但它仍然工作。

+0

thx求救! – Rene 2011-06-16 11:55:14