【问题标题】:Recursive template definition递归模板定义
【发布时间】:2011-06-16 11:11:53
【问题描述】:

我有一个递归模板定义(我只是编造了那个术语)。我认为代码解释得更好。

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 的实例

有人遇到过这个问题吗?您提出了哪些解决方案?

【问题讨论】:

  • 您是否正在尝试使用模板元编程来处理多项式?我认为这已经完成了:-)
  • 恭喜,您发现了模板元编程。
  • 我应该停止使用 stackoverflow。这是唯一让我感到愚蠢的地方。我不敢相信我多年来一直称自己为软件工程师。
  • @Rene 你不应该把我们的 cmets 当作气馁。事实上,一个人提出模板元编程的核心概念绝非易事。在 C++ 中的模板正式化之后,人们花了数年时间才注意到它们的潜力。

标签: c++ templates recursion definition


【解决方案1】:

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

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

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

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

你的会是部分而不是完整的,但它仍然可以工作。

【讨论】:

    【解决方案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 案例。

    作为建议,获取一些有关模板元编程的书籍或教程等。一种基本技术是以这种方式在模板中使用递归。这严格来说还不是元编程,它只是递归模板。这本书/教程将解释更高级的技巧是如何工作的,您可以在扩展时使用这些技巧。

    这样做的原因是原始代码仍会将编译时“if”扩展为运行时代码(永远不会执行)。这段代码用不存在的情况替换了可以编译出来的一种情况,因此没有无限递归的选项。

    【讨论】:

    • 谢谢!我读了它,这似乎是合乎逻辑的。我试试看。
    猜你喜欢
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    相关资源
    最近更新 更多